llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Sathwik Kodamarthi (siddu0660)

<details>
<summary>Changes</summary>



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

``````````

</details>


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

Reply via email to