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/3] 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/3] 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
 
//===----------------------------------------------------------------------===//

>From 267c6baecc025b7020469101665997019cf80606 Mon Sep 17 00:00:00 2001
From: spamprx <[email protected]>
Date: Fri, 7 Nov 2025 17:25:48 +0530
Subject: [PATCH 3/3] Remove redundant CIR_BinOpOverflow and implement
 CIR_IsConstantOp in CIRGenBuiltin

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 117 ++++++-------------
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp      |  56 +++++----
 2 files changed, 72 insertions(+), 101 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 63d31d36fe933..5d0913dae3308 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1702,47 +1702,6 @@ 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
 
//===----------------------------------------------------------------------===//
@@ -3084,6 +3043,44 @@ def CIR_ArrayDtor : CIR_ArrayInitDestroy<"array.dtor"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// 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_BoolType:$result);
+
+  let assemblyFormat = [{
+    `(` $value `:` type($value) `)` `:` type($result) attr-dict
+  }];
+
+  // let hasFolder = 1;
+  // let hasLLVMLowering = false;
+}
+
 
//===----------------------------------------------------------------------===//
 // VecCreate
 
//===----------------------------------------------------------------------===//
@@ -4093,44 +4090,6 @@ 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 6ef4ee3dfe612..b7219063c9d43 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -201,28 +201,40 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   }
   
   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);
+    mlir::Location loc = getLoc(e->getSourceRange());
+    mlir::Type ResultType = convertType(e->getType());
+
+    const Expr *Arg = e->getArg(0);
+    QualType ArgType = Arg->getType();
+    // FIXME: The allowance for Obj-C pointers and block pointers is historical
+    // and likely a mistake.
+    if (!ArgType->isIntegralOrEnumerationType() && !ArgType->isFloatingType() 
&&
+        !ArgType->isObjCObjectPointerType() && !ArgType->isBlockPointerType())
+      // Per the GCC documentation, only numeric constants are recognized after
+      // inlining.
+      return RValue::get(
+          builder.getConstInt(getLoc(e->getSourceRange()),
+                              mlir::cast<cir::IntType>(ResultType), 0));
+
+    if (Arg->HasSideEffects(getContext()))
+      // The argument is unevaluated, so be conservative if it might have
+      // side-effects.
+      return RValue::get(
+          builder.getConstInt(getLoc(e->getSourceRange()),
+                              mlir::cast<cir::IntType>(ResultType), 0));
+
+    mlir::Value ArgValue = emitScalarExpr(Arg);
+    if (ArgType->isObjCObjectPointerType())
+      // Convert Objective-C objects to id because we cannot distinguish 
between
+      // LLVM types for Obj-C classes as they are opaque.
+      ArgType = cgm.getASTContext().getObjCIdType();
+    ArgValue = builder.createBitcast(ArgValue, convertType(ArgType));
+
+    mlir::Value Result = cir::IsConstantOp::create(
+        builder, getLoc(e->getSourceRange()), ArgValue);
+    if (Result.getType() != ResultType)
+      Result = builder.createBoolToInt(Result, ResultType);
+    return RValue::get(Result);
   }
 
   case Builtin::BIcos:

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

Reply via email to