[clang] feat: included support for is_constant builtin (PR #166832)

2025-12-02 Thread Andy Kaylor via cfe-commits

andykaylor wrote:

This was handled by https://github.com/llvm/llvm-project/pull/170354

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-12-02 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor closed 
https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-11 Thread Henrich Lauko via cfe-commits


@@ -3043,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.

xlauko wrote:

This is not true, the expected result is bool

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-11 Thread Henrich Lauko via cfe-commits


@@ -3043,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 -> !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;

xlauko wrote:

Remove this or implement folder as well.

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-11 Thread Henrich Lauko via cfe-commits


@@ -4052,6 +4093,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 -> !s32i
+```
+  }];
+
+  let arguments = (ins CIR_AnyType:$value);
+  let results = (outs CIR_SInt32:$result);
+
+  let assemblyFormat = [{
+$value `:` type($value) `->` type($result) attr-dict

xlauko wrote:

@andykaylor pretty much yes. I am traying us to converge on style `: argument 
types -> return types` respectivelly `: type` if the operation can be 
determined by a single type. Bit of style guide is in: 
https://llvm.github.io/clangir/Dialect/cir-style-guide.html



https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-11 Thread Henrich Lauko via cfe-commits


@@ -199,6 +199,43 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 return RValue::get(
 builder.createBitcast(allocaAddr, builder.getVoidPtrTy()));
   }
+  
+  case Builtin::BI__builtin_constant_p: { 
+mlir::Location loc = getLoc(e->getSourceRange());
+mlir::Type ResultType = convertType(e->getType());
+
+const Expr *Arg = e->getArg(0);
+QualType ArgType = Arg->getType();

xlauko wrote:

```suggestion
const Expr *arg = e->getArg(0);
QualType argType = arg->getType();
```

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-07 Thread via cfe-commits

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

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx 
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 -> !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
 
//===-

[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-07 Thread via cfe-commits

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

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx 
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 -> !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
 
//===-

[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread Sathwik Kodamarthi via cfe-commits


@@ -4052,6 +4093,44 @@ def CIR_ExpectOp : CIR_Op<"expect", [
   }];
 }
 
+//===--===//
+// IsConstantOp

siddu0660 wrote:

Thanks for mentioning the incubator ! I hadn’t come across that detail earlier, 
but I appreciate you pointing it out. I’ll go through it and make sure I’m 
aligned before moving forward.

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread via cfe-commits

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

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx 
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 -> !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
 
//===-

[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread Andy Kaylor via cfe-commits

andykaylor wrote:

Hi @siddu0660. Thanks for working on this! I appreciate that you were proactive 
in getting started on this. Unfortunately, that probably resulted in a bit of 
duplicated effort as @adams381 is also working on this, but I can see that you 
had probably started before I added the comment in 
https://github.com/llvm/llvm-project/issues/163889 explaining that.

I'll review the PR in a minute, but my first feedback is that the title should 
begin with `[CIR]` for CIR-related work. This is obviously a minor point, but 
as this is your first contribution I'm going to point out many small things 
like this to introduce you to our usual practices.

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread Sathwik Kodamarthi via cfe-commits

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

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx 
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 -> !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
 
//===---

[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clangir

Author: Sathwik Kodamarthi (siddu0660)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/166832.diff


3 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+38) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+25) 
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+19) 


``diff
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 -> !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
 
//===--===//

``




https://github.com/llvm/llvm-project/pull/166832
_

[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/166832
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] feat: included support for is_constant builtin (PR #166832)

2025-11-06 Thread Sathwik Kodamarthi via cfe-commits

https://github.com/siddu0660 created 
https://github.com/llvm/llvm-project/pull/166832

None

>From 227f9ad624e570353abff8de7a09b276e9c6b4e2 Mon Sep 17 00:00:00 2001
From: spamprx 
Date: Fri, 7 Nov 2025 00:55:26 +0530
Subject: [PATCH] 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 -> !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
 
//===-