Skip to content

Conversation

@xlauko
Copy link
Contributor

@xlauko xlauko commented Jul 29, 2025

  • Replaces dyn_castcir::ConstantOp(v.getDefiningOp()) and similar with v.getDefiningOpcir::ConstantOp()
  • Adds getValueAttr method to ConstantOp

@xlauko
Copy link
Contributor Author

xlauko commented Jul 29, 2025

@xlauko xlauko requested a review from erichkeane July 29, 2025 20:00
@xlauko xlauko marked this pull request as ready for review July 29, 2025 20:00
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Jul 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 29, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Henrich Lauko (xlauko)

Changes
  • Replaces dyn_cast<cir::ConstantOp>(v.getDefiningOp()) and similar with v.getDefiningOp<cir::ConstantOp>()
  • Adds getValueAttr, getIntValue and getBoolValue methods to ConstantOp

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

7 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+15)
  • (modified) clang/lib/CIR/CodeGen/CIRGenClass.cpp (+10-9)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+3-4)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+2-2)
  • (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+1-1)
  • (modified) clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp (+8-14)
  • (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+2-3)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index e5a0ba707e0e2..ae842e988b3bb 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -291,6 +291,21 @@ def CIR_ConstantOp : CIR_Op<"const", [
         return ptrAttr.isNullValue();
       return false;
     }
+
+    template <typename T>
+    T getValueAttr() { return mlir::dyn_cast<T>(getValue()); }
+
+    llvm::APInt getIntValue() {
+      if (const auto intAttr = getValueAttr<cir::IntAttr>())
+        return intAttr.getValue();
+      llvm_unreachable("Expected an IntAttr in ConstantOp");
+    }
+
+    bool getBoolValue() {
+      if (const auto boolAttr = getValueAttr<cir::BoolAttr>())
+        return boolAttr.getValue();
+      llvm_unreachable("Expected a BoolAttr in ConstantOp");
+    }
   }];
 
   let hasFolder = 1;
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 50cca0e63611e..72b9d177e4c63 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -349,12 +349,16 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
   // doesn't happen, but it's not clear that it's worth it.
 
   // Optimize for a constant count.
-  auto constantCount = dyn_cast<cir::ConstantOp>(numElements.getDefiningOp());
-  if (constantCount) {
-    auto constIntAttr = mlir::dyn_cast<cir::IntAttr>(constantCount.getValue());
-    // Just skip out if the constant count is zero.
-    if (constIntAttr && constIntAttr.getUInt() == 0)
-      return;
+  if (auto constantCount = numElements.getDefiningOp<cir::ConstantOp>()) {
+    if (auto constIntAttr = constantCount.getValueAttr<cir::IntAttr>()) {
+      // Just skip out if the constant count is zero.
+      if (constIntAttr.getUInt() == 0)
+        return;
+      // Otherwise, emit the check.
+    }
+
+    if (constantCount.use_empty())
+      constantCount.erase();
   } else {
     // Otherwise, emit the check.
     cgm.errorNYI(e->getSourceRange(), "dynamic-length array expression");
@@ -417,9 +421,6 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
           builder.create<cir::YieldOp>(loc);
         });
   }
-
-  if (constantCount.use_empty())
-    constantCount.erase();
 }
 
 void CIRGenFunction::emitDelegateCXXConstructorCall(
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 64dc1ce1d1e20..3a6732394f1cb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -712,8 +712,8 @@ static const Expr *getSimpleArrayDecayOperand(const Expr *e) {
 
 static cir::IntAttr getConstantIndexOrNull(mlir::Value idx) {
   // TODO(cir): should we consider using MLIRs IndexType instead of IntegerAttr?
-  if (auto constantOp = dyn_cast<cir::ConstantOp>(idx.getDefiningOp()))
-    return mlir::dyn_cast<cir::IntAttr>(constantOp.getValue());
+  if (auto constantOp = idx.getDefiningOp<cir::ConstantOp>())
+    return constantOp.getValueAttr<cir::IntAttr>();
   return {};
 }
 
@@ -721,8 +721,7 @@ static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx,
                                       CharUnits eltSize) {
   // If we have a constant index, we can use the exact offset of the
   // element we're accessing.
-  const cir::IntAttr constantIdx = getConstantIndexOrNull(idx);
-  if (constantIdx) {
+  if (const cir::IntAttr constantIdx = getConstantIndexOrNull(idx)) {
     const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
     return arrayAlign.alignmentAtOffset(offset);
   }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 2523b0ff33787..41243a77d9df6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -48,8 +48,8 @@ struct BinOpInfo {
   /// Check if the binop can result in integer overflow.
   bool mayHaveIntegerOverflow() const {
     // Without constant input, we can't rule out overflow.
-    auto lhsci = dyn_cast<cir::ConstantOp>(lhs.getDefiningOp());
-    auto rhsci = dyn_cast<cir::ConstantOp>(rhs.getDefiningOp());
+    auto lhsci = lhs.getDefiningOp<cir::ConstantOp>();
+    auto rhsci = rhs.getDefiningOp<cir::ConstantOp>();
     if (!lhsci || !rhsci)
       return true;
 
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 35408bfcb8ba7..6cde1fc2d300e 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -1826,7 +1826,7 @@ LogicalResult cir::GetMemberOp::verify() {
 
 OpFoldResult cir::VecCreateOp::fold(FoldAdaptor adaptor) {
   if (llvm::any_of(getElements(), [](mlir::Value value) {
-        return !mlir::isa<cir::ConstantOp>(value.getDefiningOp());
+        return !value.getDefiningOp<cir::ConstantOp>();
       }))
     return {};
 
diff --git a/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp b/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
index 3b7f08c441405..3c6f76892d5cb 100644
--- a/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
@@ -97,8 +97,8 @@ struct SimplifyTernary final : public OpRewritePattern<TernaryOp> {
     // Check whether the region/block contains a cir.const followed by a
     // cir.yield that yields the value.
     auto yieldOp = mlir::cast<cir::YieldOp>(onlyBlock.getTerminator());
-    auto yieldValueDefOp = mlir::dyn_cast_if_present<cir::ConstantOp>(
-        yieldOp.getArgs()[0].getDefiningOp());
+    auto yieldValueDefOp =
+        yieldOp.getArgs()[0].getDefiningOp<cir::ConstantOp>();
     return yieldValueDefOp && yieldValueDefOp->getBlock() == &onlyBlock;
   }
 };
@@ -126,18 +126,13 @@ struct SimplifySelect : public OpRewritePattern<SelectOp> {
 
   LogicalResult matchAndRewrite(SelectOp op,
                                 PatternRewriter &rewriter) const final {
-    mlir::Operation *trueValueOp = op.getTrueValue().getDefiningOp();
-    mlir::Operation *falseValueOp = op.getFalseValue().getDefiningOp();
-    auto trueValueConstOp =
-        mlir::dyn_cast_if_present<cir::ConstantOp>(trueValueOp);
-    auto falseValueConstOp =
-        mlir::dyn_cast_if_present<cir::ConstantOp>(falseValueOp);
-    if (!trueValueConstOp || !falseValueConstOp)
+    auto trueValueOp = op.getTrueValue().getDefiningOp<cir::ConstantOp>();
+    auto falseValueOp = op.getFalseValue().getDefiningOp<cir::ConstantOp>();
+    if (!trueValueOp || !falseValueOp)
       return mlir::failure();
 
-    auto trueValue = mlir::dyn_cast<cir::BoolAttr>(trueValueConstOp.getValue());
-    auto falseValue =
-        mlir::dyn_cast<cir::BoolAttr>(falseValueConstOp.getValue());
+    auto trueValue = trueValueOp.getValueAttr<cir::BoolAttr>();
+    auto falseValue = falseValueOp.getValueAttr<cir::BoolAttr>();
     if (!trueValue || !falseValue)
       return mlir::failure();
 
@@ -265,8 +260,7 @@ struct SimplifyVecSplat : public OpRewritePattern<VecSplatOp> {
   LogicalResult matchAndRewrite(VecSplatOp op,
                                 PatternRewriter &rewriter) const override {
     mlir::Value splatValue = op.getValue();
-    auto constant =
-        mlir::dyn_cast_if_present<cir::ConstantOp>(splatValue.getDefiningOp());
+    auto constant = splatValue.getDefiningOp<cir::ConstantOp>();
     if (!constant)
       return mlir::failure();
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0ed632fa09c05..b15205f95bc95 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1874,12 +1874,11 @@ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite(
     cir::SelectOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
   auto getConstantBool = [](mlir::Value value) -> cir::BoolAttr {
-    auto definingOp =
-        mlir::dyn_cast_if_present<cir::ConstantOp>(value.getDefiningOp());
+    auto definingOp = value.getDefiningOp<cir::ConstantOp>();
     if (!definingOp)
       return {};
 
-    auto constValue = mlir::dyn_cast<cir::BoolAttr>(definingOp.getValue());
+    auto constValue = definingOp.getValueAttr<cir::BoolAttr>();
     if (!constValue)
       return {};
 

@xlauko xlauko force-pushed the users/xlauko/cir-constant-op-accesses branch from f149cb8 to 1770a46 Compare August 1, 2025 14:58
@xlauko
Copy link
Contributor Author

xlauko commented Aug 1, 2025

@andykaylor ping

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great

@xlauko xlauko force-pushed the users/xlauko/cir-constant-op-accesses branch 4 times, most recently from 3f27255 to 2312172 Compare August 1, 2025 18:05
@xlauko
Copy link
Contributor Author

xlauko commented Aug 1, 2025

Merge activity

  • Aug 1, 6:06 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 1, 6:18 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 1, 6:21 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 1, 6:37 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 1, 6:40 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 1, 7:04 PM UTC: @xlauko merged this pull request with Graphite.

@xlauko xlauko force-pushed the users/xlauko/cir-constant-op-accesses branch 3 times, most recently from 3760465 to 05b0240 Compare August 1, 2025 18:37
- Replaces  dyn_cast<cir::ConstantOp>(v.getDefiningOp()) and similar with v.getDefiningOp<cir::ConstantOp>()
- Adds `getValueAttr`, `getIntValue` and `getBoolValue` methods to ConstantOp
@xlauko xlauko force-pushed the users/xlauko/cir-constant-op-accesses branch from 05b0240 to 88e5e8b Compare August 1, 2025 18:40
@xlauko xlauko merged commit 4820b18 into main Aug 1, 2025
9 checks passed
@xlauko xlauko deleted the users/xlauko/cir-constant-op-accesses branch August 1, 2025 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants