https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/214551
>From 0bcd8c4af0b6b189d0f70a03ac006d8d0d5ad065 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Fri, 7 Aug 2026 00:30:05 +0530 Subject: [PATCH 1/3] [CIR] Avoid folding non-integer constants as integer casts CIRGen may produce undef constants while recovering from NYI builtin lowering. When such a value feeds an implicit integral cast, CastOp::fold currently treats the source as an integer constant solely because it is a cir.constant, then calls getIntValue() and crashes. Added a check for the constant to see if the payload is actually an IntAttr before folding the cast. If it is not, return the cast unfolded. Added a regression test covering an unimplemented __builtin_stdc_* call whose undef result was implicitly being cast to integer by CastOp::fold. --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 9 +++++++-- clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index cd94219655e02..ca4d14f61cacd 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1013,10 +1013,15 @@ OpFoldResult cir::CastOp::fold(FoldAdaptor adaptor) { auto srcIntTy = mlir::cast<cir::IntType>(srcTy); auto dstIntTy = mlir::cast<cir::IntType>(getType()); + auto constIntAttr = srcConst.getValueAttr<cir::IntAttr>(); + if (!constIntAttr) + return {}; + + APInt srcValue = constIntAttr.getValue(); APInt newVal = srcIntTy.isSigned() - ? srcConst.getIntValue().sextOrTrunc(dstIntTy.getWidth()) - : srcConst.getIntValue().zextOrTrunc(dstIntTy.getWidth()); + ? srcValue.sextOrTrunc(dstIntTy.getWidth()) + : srcValue.zextOrTrunc(dstIntTy.getWidth()); return cir::IntAttr::get(dstIntTy, newVal); } default: diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c b/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c new file mode 100644 index 0000000000000..e74f295aa6931 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -verify %s -o - + +void test_stdc_trailing_zeros_undef_cast(unsigned long long x) { + // expected-error@+1 {{ClangIR code gen Not Yet Implemented: unimplemented builtin call: __builtin_stdc_trailing_zeros}} + int cnt = __builtin_stdc_trailing_zeros(x); + (void)cnt; +} >From 26425371e19300ab478078c5cfb3d8bfac4de9eb Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Fri, 7 Aug 2026 06:35:10 +0530 Subject: [PATCH 2/3] [CIR] Propagate UndefAttr through CastOp::fold Propagates UndefAtrr similar to Poison propagation, keeping the IntAttr guard in place. --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 11 +++++++---- clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c | 5 ++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index ca4d14f61cacd..d5d9c2669ce7c 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -975,6 +975,10 @@ OpFoldResult cir::CastOp::fold(FoldAdaptor adaptor) { return cir::PoisonAttr::get(getContext(), getType()); } + // Propagate Undef value + if (mlir::isa_and_present<cir::UndefAttr>(adaptor.getSrc())) + return cir::UndefAttr::get(getType()); + if (getSrc().getType() == getType()) { switch (getKind()) { case cir::CastKind::integral: { @@ -1018,10 +1022,9 @@ OpFoldResult cir::CastOp::fold(FoldAdaptor adaptor) { return {}; APInt srcValue = constIntAttr.getValue(); - APInt newVal = - srcIntTy.isSigned() - ? srcValue.sextOrTrunc(dstIntTy.getWidth()) - : srcValue.zextOrTrunc(dstIntTy.getWidth()); + APInt newVal = srcIntTy.isSigned() + ? srcValue.sextOrTrunc(dstIntTy.getWidth()) + : srcValue.zextOrTrunc(dstIntTy.getWidth()); return cir::IntAttr::get(dstIntTy, newVal); } default: diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c b/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c index e74f295aa6931..2d0894da0bdbf 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c @@ -1,7 +1,10 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -verify %s -o - +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -verify %s -o - | FileCheck %s void test_stdc_trailing_zeros_undef_cast(unsigned long long x) { // expected-error@+1 {{ClangIR code gen Not Yet Implemented: unimplemented builtin call: __builtin_stdc_trailing_zeros}} int cnt = __builtin_stdc_trailing_zeros(x); (void)cnt; } + +// CHECK-LABEL: test_stdc_trailing_zeros_undef_cast +// CHECK: cir.const #cir.undef : !s32i >From 962374a9a379006555a6db24c64f6f4935aeeab8 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Sun, 9 Aug 2026 13:51:25 +0530 Subject: [PATCH 3/3] [CIR] moved undef fold test to canonicalize.cir Moved undef cast during CastOp::fold to canonicalize.cir to directly test the cast folding rather than relying to NYI function to test it. --- clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c | 10 ---------- clang/test/CIR/Transforms/canonicalize.cir | 9 +++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c b/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c deleted file mode 100644 index 2d0894da0bdbf..0000000000000 --- a/clang/test/CIR/CodeGenBuiltins/builtin-stdc-bit-nyi.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -verify %s -o - | FileCheck %s - -void test_stdc_trailing_zeros_undef_cast(unsigned long long x) { - // expected-error@+1 {{ClangIR code gen Not Yet Implemented: unimplemented builtin call: __builtin_stdc_trailing_zeros}} - int cnt = __builtin_stdc_trailing_zeros(x); - (void)cnt; -} - -// CHECK-LABEL: test_stdc_trailing_zeros_undef_cast -// CHECK: cir.const #cir.undef : !s32i diff --git a/clang/test/CIR/Transforms/canonicalize.cir b/clang/test/CIR/Transforms/canonicalize.cir index f8428cca7fd91..29b1d880a3748 100644 --- a/clang/test/CIR/Transforms/canonicalize.cir +++ b/clang/test/CIR/Transforms/canonicalize.cir @@ -212,6 +212,15 @@ module { // CHECK-NEXT: cir.return %[[P]] : !s64i // CHECK-NEXT: } + cir.func @cast_undef() -> !s64i { + %0 = cir.const #cir.undef : !s32i + %1 = cir.cast integral %0 : !s32i -> !s64i + cir.return %1 : !s64i + } + // CHECK: @cast_undef + // CHECK-NEXT: %[[U:.+]] = cir.const #cir.undef : !s64i + // CHECK-NEXT: cir.return %[[U]] : !s64i + cir.func @cast_s32_s64() -> !s64i { %0 = cir.const #cir.int<2> : !s32i %1 = cir.cast integral %0 : !s32i -> !s64i _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
