https://github.com/spamprx updated 
https://github.com/llvm/llvm-project/pull/166832

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx <[email protected]>
Date: Fri, 7 Nov 2025 00:55:26 +0530
Subject: [PATCH 1/2] feat: included support for is_constant builtin

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 38 ++++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp      | 25 +++++++++++++
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp      | 19 ++++++++++
 3 files changed, 82 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 2b361ed0982c6..9765684a1cd72 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4052,6 +4052,44 @@ def CIR_ExpectOp : CIR_Op<"expect", [
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// IsConstantOp
+//===----------------------------------------------------------------------===//
+
+def CIR_IsConstantOp : CIR_Op<"is_constant", [Pure]> {
+  let summary = "Check if a value is a compile-time constant";
+  let description = [{
+    The `cir.is_constant` operation checks whether its input value is a
+    compile-time constant. This operation models the `__builtin_constant_p`
+    builtin function.
+
+    The operation takes a single operand of any CIR type and returns a signed
+    32-bit integer. The result is 1 if the operand is a compile-time constant,
+    and 0 otherwise.
+
+    If the value can be determined to be constant at compile time, this
+    operation may be folded to a constant value. Otherwise, it will be lowered
+    to the `llvm.is.constant` intrinsic.
+
+    Example:
+
+    ```mlir
+    %0 = cir.is_constant %expr : i32 -> !s32i
+    %1 = cir.is_constant %ptr : !cir.ptr<i32> -> !s32i
+    ```
+  }];
+
+  let arguments = (ins CIR_AnyType:$value);
+  let results = (outs CIR_SInt32:$result);
+
+  let assemblyFormat = [{
+    $value `:` type($value) `->` type($result) attr-dict
+  }];
+
+  let hasFolder = 1;
+  let hasLLVMLowering = false;
+}
+
 
//===----------------------------------------------------------------------===//
 // PrefetchOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index e35100ffe4b6b..8777ff16f068f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -199,6 +199,31 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     return RValue::get(
         builder.createBitcast(allocaAddr, builder.getVoidPtrTy()));
   }
+  
+  case Builtin::BI__builtin_constant_p: { 
+    auto loc = getLoc(e->getSourceRange());
+  
+    Expr::EvalResult evalResult;
+    
+    // Try to evaluate at compile time first
+    if (e->getArg(0)->EvaluateAsRValue(evalResult, getContext()) &&
+        !evalResult.hasSideEffects()) {
+      // Expression is a compile-time constant, return 1
+      llvm::APInt apInt(32, 1);
+      llvm::APSInt apSInt(apInt, /*isUnsigned=*/false);
+      return RValue::get(builder.getConstInt(loc, apSInt));
+    }
+    
+    // Expression cannot be evaluated at compile time, emit runtime check
+    mlir::Value argValue = emitScalarExpr(e->getArg(0));
+    mlir::Type resultType = builder.getSInt32Ty();
+    auto isConstantOp = cir::IsConstantOp::create(builder, loc, resultType, 
argValue);
+    mlir::Value resultValue = isConstantOp.getResult();
+    mlir::Type exprTy = convertType(e->getType());
+    if (exprTy != resultValue.getType())
+      resultValue = builder.createIntCast(resultValue, exprTy);
+    return RValue::get(resultValue);
+  }
 
   case Builtin::BIcos:
   case Builtin::BIcosf:
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 7ba03ce40140c..de23514cf5a79 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2117,6 +2117,25 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) {
   return {};
 }
 
+//===----------------------------------------------------------------------===//
+// IsConstantOp Definitions
+//===----------------------------------------------------------------------===//
+
+OpFoldResult cir::IsConstantOp::fold(FoldAdaptor adaptor) {
+  // If the input value is a constant attribute, return 1 (true)
+  mlir::Attribute value = adaptor.getValue();
+  if (value) {
+    // The value is a compile-time constant, so return 1
+    mlir::Type resultType = getResult().getType();
+    llvm::APInt apInt(32, 1);
+    llvm::APSInt apSInt(apInt, /*isUnsigned=*/false);
+    return cir::IntAttr::get(resultType, apSInt);
+  }
+  
+  // If the input is not a constant, we cannot fold
+  return {};
+}
+
 
//===----------------------------------------------------------------------===//
 // CopyOp Definitions
 
//===----------------------------------------------------------------------===//

>From f2d9b64ec396de9a57366fa826284bd652128222 Mon Sep 17 00:00:00 2001
From: siddu0660 <[email protected]>
Date: Fri, 7 Nov 2025 01:18:51 +0530
Subject: [PATCH 2/2] feat: updated TableGen code for BinOpOverFlow

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 41 ++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 9765684a1cd72..44b5fb484510a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1702,6 +1702,47 @@ def CIR_BinOp : CIR_Op<"binop", [
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// BinOpOverflow
+//===----------------------------------------------------------------------===//
+
+def CIR_BinOpOverflow : CIR_Op<"binop.overflow", [Pure]> {
+  let summary = "Binary operations with overflow detection";
+  let description = [{
+    cir.binop.overflow performs the binary operation according to
+    the specified opcode kind (add, sub, or mul) and returns both
+    the result and an overflow flag.
+
+    It requires two input operands and returns two results:
+    - The result of the operation (same type as operands)
+    - An overflow flag (boolean type)
+
+    The operation supports both signed and unsigned integer types.
+    For signed types, overflow is detected when the result cannot
+    be represented in the result type. For unsigned types, overflow
+    is detected when the result wraps around.
+
+    ```mlir
+    %result, %overflow = cir.binop.overflow(add, %1, %2) : !s32i -> (!s32i, 
!bool)
+    %result, %overflow = cir.binop.overflow(sub, %3, %4) : !u32i -> (!u32i, 
!bool)
+    %result, %overflow = cir.binop.overflow(mul, %5, %6) : !s64i -> (!s64i, 
!bool)
+    ```
+  }];
+
+  let arguments = (ins
+    CIR_BinOpKind:$kind,
+    CIR_AnyType:$lhs, CIR_AnyType:$rhs
+  );
+
+  let results = (outs CIR_AnyType:$result, CIR_BoolType:$overflow);
+
+  let assemblyFormat = [{
+    `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `->` `(` type($result) `,` 
type($overflow) `)` attr-dict
+  }];
+
+  let hasVerifier = 1;
+}
+
 
//===----------------------------------------------------------------------===//
 // ShiftOp
 
//===----------------------------------------------------------------------===//

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to