[clang] d815e84 - [CIR] Implement simple folding for integer casts (#174861)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 7 14:46:52 PST 2026
Author: Andy Kaylor
Date: 2026-01-07T14:46:47-08:00
New Revision: d815e8448fa42252a5d7434d881db1f60eb3147e
URL: https://github.com/llvm/llvm-project/commit/d815e8448fa42252a5d7434d881db1f60eb3147e
DIFF: https://github.com/llvm/llvm-project/commit/d815e8448fa42252a5d7434d881db1f60eb3147e.diff
LOG: [CIR] Implement simple folding for integer casts (#174861)
This extends the CastOp folder to handle integral casts between
different integer types. This only handles scalar values at this time.
This is in preparation for a change that will attempt to fold casts as
they are generated, but this change only performs the folding via the
cir-canonicalize pass.
Added:
Modified:
clang/lib/CIR/Dialect/IR/CIRDialect.cpp
clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
clang/test/CIR/CodeGen/assign-operator.cpp
clang/test/CIR/CodeGen/binassign.c
clang/test/CIR/CodeGen/comma.c
clang/test/CIR/CodeGen/cxx-default-init.cpp
clang/test/CIR/CodeGen/enum.cpp
clang/test/CIR/CodeGen/finegrain-bitfield-access.cpp
clang/test/CIR/CodeGen/struct.cpp
clang/test/CIR/CodeGen/union.c
clang/test/CIR/CodeGen/vla.c
clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
clang/test/CIR/CodeGenBuiltins/X86/avx512vl-builtins.c
clang/test/CIR/CodeGenBuiltins/X86/xop-builtins.c
clang/test/CIR/Transforms/canonicalize.cir
clang/test/CIR/Transforms/switch.cir
Removed:
################################################################################
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index e1df5d5185a04..a17dade12ed24 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -705,8 +705,6 @@ OpFoldResult cir::CastOp::fold(FoldAdaptor adaptor) {
if (getSrc().getType() == getType()) {
switch (getKind()) {
case cir::CastKind::integral: {
- // TODO: for sign
diff erences, it's possible in certain conditions to
- // create a new attribute that's capable of representing the source.
llvm::SmallVector<mlir::OpFoldResult, 1> foldResults;
auto foldOrder = getSrc().getDefiningOp()->fold(foldResults);
if (foldOrder.succeeded() && mlir::isa<mlir::Attribute>(foldResults[0]))
@@ -723,7 +721,36 @@ OpFoldResult cir::CastOp::fold(FoldAdaptor adaptor) {
return {};
}
}
- return tryFoldCastChain(*this);
+
+ // Handle cases where a chain of casts cancel out.
+ Value result = tryFoldCastChain(*this);
+ if (result)
+ return result;
+
+ // Handle simple constant casts.
+ if (auto srcConst = getSrc().getDefiningOp<cir::ConstantOp>()) {
+ switch (getKind()) {
+ case cir::CastKind::integral: {
+ mlir::Type srcTy = getSrc().getType();
+ // Don't try to fold vector casts for now.
+ assert(mlir::isa<cir::VectorType>(srcTy) ==
+ mlir::isa<cir::VectorType>(getType()));
+ if (mlir::isa<cir::VectorType>(srcTy))
+ break;
+
+ auto srcIntTy = mlir::cast<cir::IntType>(srcTy);
+ auto dstIntTy = mlir::cast<cir::IntType>(getType());
+ APInt newVal =
+ srcIntTy.isSigned()
+ ? srcConst.getIntValue().sextOrTrunc(dstIntTy.getWidth())
+ : srcConst.getIntValue().zextOrTrunc(dstIntTy.getWidth());
+ return cir::IntAttr::get(dstIntTy, newVal);
+ }
+ default:
+ break;
+ }
+ }
+ return {};
}
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c b/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
index 66891f9e1ad78..5218a29848fb0 100644
--- a/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
+++ b/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
@@ -179,11 +179,10 @@ void check_store(st2 *s2) {
}
// CIR: cir.func {{.*}} @check_store
-// CIR: [[CONST:%.*]] = cir.const #cir.int<1> : !s32i
-// CIR: [[CAST:%.*]] = cir.cast integral [[CONST]] : !s32i -> !s16i
+// CIR: [[CONST:%.*]] = cir.const #cir.int<1> : !s16i
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st2>>, !cir.ptr<!rec_st2>
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][0] {name = "a"} : !cir.ptr<!rec_st2> -> !cir.ptr<!u32i>
-// CIR: [[SETBF:%.*]] = cir.set_bitfield align(8) (#bfi_a, [[MEMBER]] : !cir.ptr<!u32i>, [[CAST]] : !s16i) {is_volatile} -> !s16i
+// CIR: [[SETBF:%.*]] = cir.set_bitfield align(8) (#bfi_a, [[MEMBER]] : !cir.ptr<!u32i>, [[CONST]] : !s16i) {is_volatile} -> !s16i
// CIR: cir.return
// LLVM:define dso_local void @check_store
@@ -210,11 +209,10 @@ void check_store_exception(st3 *s3) {
}
// CIR: cir.func {{.*}} @check_store_exception
-// CIR: [[CONST:%.*]] = cir.const #cir.int<2> : !s32i
-// CIR: [[CAST:%.*]] = cir.cast integral [[CONST]] : !s32i -> !u32i
+// CIR: [[CONST:%.*]] = cir.const #cir.int<2> : !u32i
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st3>>, !cir.ptr<!rec_st3>
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][2] {name = "b"} : !cir.ptr<!rec_st3> -> !cir.ptr<!u8i>
-// CIR: [[SETBF:%.*]] = cir.set_bitfield align(4) (#bfi_b1, [[MEMBER]] : !cir.ptr<!u8i>, [[CAST]] : !u32i) {is_volatile} -> !u32i
+// CIR: [[SETBF:%.*]] = cir.set_bitfield align(4) (#bfi_b1, [[MEMBER]] : !cir.ptr<!u8i>, [[CONST]] : !u32i) {is_volatile} -> !u32i
// CIR: cir.return
// LLVM:define dso_local void @check_store_exception
@@ -262,11 +260,10 @@ void check_store_second_member (st4 *s4) {
}
// CIR: cir.func {{.*}} @check_store_second_member
-// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !s32i
-// CIR: [[CAST:%.*]] = cir.cast integral [[ONE]] : !s32i -> !u64i
+// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !u64i
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st4>>, !cir.ptr<!rec_st4>
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][2] {name = "b"} : !cir.ptr<!rec_st4> -> !cir.ptr<!u16i>
-// CIR: cir.set_bitfield align(8) (#bfi_b2, [[MEMBER]] : !cir.ptr<!u16i>, [[CAST]] : !u64i) {is_volatile} -> !u64i
+// CIR: cir.set_bitfield align(8) (#bfi_b2, [[MEMBER]] : !cir.ptr<!u16i>, [[ONE]] : !u64i) {is_volatile} -> !u64i
// LLVM: define dso_local void @check_store_second_member
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
diff --git a/clang/test/CIR/CodeGen/assign-operator.cpp b/clang/test/CIR/CodeGen/assign-operator.cpp
index ad3e5c00911c4..04aaeb64e12ab 100644
--- a/clang/test/CIR/CodeGen/assign-operator.cpp
+++ b/clang/test/CIR/CodeGen/assign-operator.cpp
@@ -16,9 +16,8 @@ void a() {
// CIR: cir.func {{.*}} @_ZN1xaSEi(!cir.ptr<!rec_x>, !s32i)
// CIR: cir.func{{.*}} @_Z1av()
// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_x, !cir.ptr<!rec_x>, ["a"]
-// CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !u32i
-// CIR: %[[ONE_CAST:.*]] = cir.cast integral %[[ONE]] : !u32i -> !s32i
-// CIR: %[[RET:.*]] = cir.call @_ZN1xaSEi(%[[A_ADDR]], %[[ONE_CAST]]) : (!cir.ptr<!rec_x>, !s32i) -> !s32i
+// CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
+// CIR: %[[RET:.*]] = cir.call @_ZN1xaSEi(%[[A_ADDR]], %[[ONE]]) : (!cir.ptr<!rec_x>, !s32i) -> !s32i
// LLVM: define{{.*}} @_Z1av(){{.*}}
// OGCG: define{{.*}} @_Z1av()
diff --git a/clang/test/CIR/CodeGen/binassign.c b/clang/test/CIR/CodeGen/binassign.c
index ee4a097f7cc31..eacdb5ed35c5b 100644
--- a/clang/test/CIR/CodeGen/binassign.c
+++ b/clang/test/CIR/CodeGen/binassign.c
@@ -24,8 +24,7 @@ void binary_assign(void) {
// CIR: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i"]
// CIR: %[[TRUE:.*]] = cir.const #true
// CIR: cir.store{{.*}} %[[TRUE]], %[[B]] : !cir.bool, !cir.ptr<!cir.bool>
-// CIR: %[[CHAR_INI_INIT:.*]] = cir.const #cir.int<65> : !s32i
-// CIR: %[[CHAR_VAL:.*]] = cir.cast integral %[[CHAR_INI_INIT]] : !s32i -> !s8i
+// CIR: %[[CHAR_VAL:.*]] = cir.const #cir.int<65> : !s8i
// CIR: cir.store{{.*}} %[[CHAR_VAL]], %[[C]] : !s8i, !cir.ptr<!s8i>
// CIR: %[[FLOAT_VAL:.*]] = cir.const #cir.fp<3.140000e+00> : !cir.float
// CIR: cir.store{{.*}} %[[FLOAT_VAL]], %[[F]] : !cir.float, !cir.ptr<!cir.float>
diff --git a/clang/test/CIR/CodeGen/comma.c b/clang/test/CIR/CodeGen/comma.c
index c0bc4428354b2..764f724f9cf90 100644
--- a/clang/test/CIR/CodeGen/comma.c
+++ b/clang/test/CIR/CodeGen/comma.c
@@ -23,8 +23,7 @@ void comma(void) {
// CIR: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i"]
// CIR: %[[TRUE:.*]] = cir.const #true
// CIR: cir.store{{.*}} %[[TRUE]], %[[B]] : !cir.bool, !cir.ptr<!cir.bool>
-// CIR: %[[CHAR_INI_INIT:.*]] = cir.const #cir.int<65> : !s32i
-// CIR: %[[CHAR_VAL:.*]] = cir.cast integral %[[CHAR_INI_INIT]] : !s32i -> !s8i
+// CIR: %[[CHAR_VAL:.*]] = cir.const #cir.int<65> : !s8i
// CIR: cir.store{{.*}} %[[CHAR_VAL]], %[[C]] : !s8i, !cir.ptr<!s8i>
// CIR: %[[FLOAT_VAL:.*]] = cir.const #cir.fp<3.140000e+00> : !cir.float
// CIR: cir.store{{.*}} %[[FLOAT_VAL]], %[[F]] : !cir.float, !cir.ptr<!cir.float>
diff --git a/clang/test/CIR/CodeGen/cxx-default-init.cpp b/clang/test/CIR/CodeGen/cxx-default-init.cpp
index 3a89c77e93059..a2940971b6ce4 100644
--- a/clang/test/CIR/CodeGen/cxx-default-init.cpp
+++ b/clang/test/CIR/CodeGen/cxx-default-init.cpp
@@ -168,9 +168,8 @@ struct ValueInit {
// CIR: %[[FOUR_FIVEI:.*]] = cir.const #cir.const_complex<#cir.fp<6.000000e+00> : !cir.float, #cir.fp<7.000000e+00>
// CIR: cir.store{{.*}} %[[FOUR_FIVEI]], %[[C]]
// CIR: %[[BF:.*]] = cir.get_member %[[THIS]][4] {name = "bf"}
-// CIR: %[[FF:.*]] = cir.const #cir.int<255> : !s32i
-// CIR: %[[FF_CAST:.*]] = cir.cast integral %[[FF]] : !s32i -> !u32i
-// CIR: %[[BF_VAL:.*]] = cir.set_bitfield{{.*}} (#bfi_bf, %[[BF]] : !cir.ptr<!u8i>, %[[FF_CAST]] : !u32i)
+// CIR: %[[FF:.*]] = cir.const #cir.int<255> : !u32i
+// CIR: %[[BF_VAL:.*]] = cir.set_bitfield{{.*}} (#bfi_bf, %[[BF]] : !cir.ptr<!u8i>, %[[FF]] : !u32i)
// LLVM: define{{.*}} void @_ZN9ValueInitC2Ev(ptr %[[THIS_ARG:.*]])
// LLVM: %[[THIS_ALLOCA:.*]] = alloca ptr
diff --git a/clang/test/CIR/CodeGen/enum.cpp b/clang/test/CIR/CodeGen/enum.cpp
index 247fa0a3bfd43..5a23f91323e26 100644
--- a/clang/test/CIR/CodeGen/enum.cpp
+++ b/clang/test/CIR/CodeGen/enum.cpp
@@ -13,7 +13,7 @@ int f() {
}
// CHECK: cir.func{{.*}} @_Z1fv
-// CHECK: cir.const #cir.int<1> : !u32i
+// CHECK: cir.const #cir.int<1> : !s32i
namespace test {
using enum Numbers;
@@ -24,4 +24,4 @@ int f2() {
}
// CHECK: cir.func{{.*}} @_Z2f2v
-// CHECK: cir.const #cir.int<2> : !u32i
+// CHECK: cir.const #cir.int<2> : !s32i
diff --git a/clang/test/CIR/CodeGen/finegrain-bitfield-access.cpp b/clang/test/CIR/CodeGen/finegrain-bitfield-access.cpp
index d9ccd273ff3ba..ed50954bb2af1 100644
--- a/clang/test/CIR/CodeGen/finegrain-bitfield-access.cpp
+++ b/clang/test/CIR/CodeGen/finegrain-bitfield-access.cpp
@@ -69,10 +69,9 @@ void write8_1() {
}
// CIR-LABEL: @_Z8write8_1v
-// CIR: [[CONST3:%.*]] = cir.const #cir.int<3> : !s32i
-// CIR: [[INT3:%.*]] = cir.cast integral [[CONST3]] : !s32i -> !u32i
+// CIR: [[CONST3:%.*]] = cir.const #cir.int<3> : !u32i
// CIR: [[MEMBER:%.*]] = cir.get_member {{.*}}[1] {name = "f3"} : !cir.ptr<!rec_S1> -> !cir.ptr<!u8i>
-// CIR: cir.set_bitfield align(1) (#bfi_f3, [[MEMBER]] : !cir.ptr<!u8i>, [[INT3]] : !u32i) -> !u32i
+// CIR: cir.set_bitfield align(1) (#bfi_f3, [[MEMBER]] : !cir.ptr<!u8i>, [[CONST3]] : !u32i) -> !u32i
// LLVM-LABEL: @_Z8write8_1v
// LLVM: store i8 3, ptr getelementptr inbounds nuw (i8, ptr {{.*}}, i64 1), align 1
@@ -115,10 +114,9 @@ void write8_2() {
}
// CIR-LABEL: @_Z8write8_2v
-// CIR: [[CONST3:%.*]] = cir.const #cir.int<3> : !s32i
-// CIR: [[INT3:%.*]] = cir.cast integral [[CONST3]] : !s32i -> !u32i
+// CIR: [[CONST3:%.*]] = cir.const #cir.int<3> : !u32i
// CIR: [[MEMBER:%.*]] = cir.get_member {{.*}}[2] {name = "f5"} : !cir.ptr<!rec_S1> -> !cir.ptr<!u16i>
-// CIR: cir.set_bitfield align(2) (#bfi_f5, %3 : !cir.ptr<!u16i>, {{.*}} : !u32i) -> !u32i
+// CIR: cir.set_bitfield align(2) (#bfi_f5, [[MEMBER]] : !cir.ptr<!u16i>, [[CONST3]] : !u32i) -> !u32i
// LLVM-LABEL: @_Z8write8_2v
// LLVM: [[BFLOAD:%.*]] = load i16, ptr getelementptr inbounds nuw (i8, ptr {{.*}}, i64 2), align 2
@@ -191,10 +189,9 @@ void write16_1() {
}
// CIR-LABEL: @_Z9write16_1v
-// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !s32i
-// CIR: [[INT5:%.*]] = cir.cast integral [[CONST5]] : !s32i -> !u64i
+// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !u64i
// CIR: [[MEMBER:%.*]] = cir.get_member {{.*}}[0] {name = "f1"} : !cir.ptr<!rec_S2> -> !cir.ptr<!u16i>
-// CIR: cir.set_bitfield align(8) (#bfi_f1, [[MEMBER]] : !cir.ptr<!u16i>, [[INT5]] : !u64i) -> !u64i
+// CIR: cir.set_bitfield align(8) (#bfi_f1, [[MEMBER]] : !cir.ptr<!u16i>, [[CONST5]] : !u64i) -> !u64i
// CIR: cir.return
// LLVM-LABEL: @_Z9write16_1v
@@ -211,10 +208,9 @@ void write16_2() {
}
// CIR-LABEL: @_Z9write16_2v
-// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !s32i
-// CIR: [[INT5:%.*]] = cir.cast integral [[CONST5]] : !s32i -> !u64i
+// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !u64i
// CIR: [[MEMBER:%.*]] = cir.get_member {{.*}}[1] {name = "f2"} : !cir.ptr<!rec_S2> -> !cir.ptr<!u16i>
-// CIR: cir.set_bitfield align(2) (#bfi_f2, [[MEMBER]] : !cir.ptr<!u16i>, {{.*}} : !u64i) -> !u64i
+// CIR: cir.set_bitfield align(2) (#bfi_f2, [[MEMBER]] : !cir.ptr<!u16i>, [[CONST5]] : !u64i) -> !u64i
// CIR: cir.return
// LLVM-LABEL: @_Z9write16_2v
@@ -256,10 +252,9 @@ void write32_1() {
}
// CIR-LABEL: @_Z9write32_1v
-// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !s32i
-// CIR: [[INT5:%.*]] = cir.cast integral [[CONST5]] : !s32i -> !u64i
+// CIR: [[CONST5:%.*]] = cir.const #cir.int<5> : !u64i
// CIR: [[MEMBER:%.*]] = cir.get_member {{.*}}[1] {name = "f3"} : !cir.ptr<!rec_S3> -> !cir.ptr<!u32i>
-// CIR: cir.set_bitfield align(4) (#bfi_f3_1, [[MEMBER]] : !cir.ptr<!u32i>, [[INT5]] : !u64i) -> !u64i
+// CIR: cir.set_bitfield align(4) (#bfi_f3_1, [[MEMBER]] : !cir.ptr<!u32i>, [[CONST5]] : !u64i) -> !u64i
// CIR: cir.return
// LLVM-LABEL: @_Z9write32_1v
diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp
index dc3e24113d8d8..fffd014e21917 100644
--- a/clang/test/CIR/CodeGen/struct.cpp
+++ b/clang/test/CIR/CodeGen/struct.cpp
@@ -344,9 +344,8 @@ void calling_function_with_default_values() {
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
// CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
// CIR: %[[ELEM_1_PTR:.*]] = cir.get_member %[[AGG_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>
-// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
-// CIR: %[[CONST_2_I8:.*]] = cir.cast integral %[[CONST_2]] : !s32i -> !s8i
-// CIR: cir.store{{.*}} %[[CONST_2_I8]], %[[ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>
+// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s8i
+// CIR: cir.store{{.*}} %[[CONST_2]], %[[ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>
// CIR: %[[TMP_AGG:.*]] = cir.load{{.*}} %[[AGG_ADDR]] : !cir.ptr<!rec_CompleteS>, !rec_CompleteS
// CIR: cir.call @_Z31function_arg_with_default_value9CompleteS(%[[TMP_AGG]]) : (!rec_CompleteS) -> ()
diff --git a/clang/test/CIR/CodeGen/union.c b/clang/test/CIR/CodeGen/union.c
index 5237d2be924ec..b0f482fd7e07d 100644
--- a/clang/test/CIR/CodeGen/union.c
+++ b/clang/test/CIR/CodeGen/union.c
@@ -115,10 +115,9 @@ void shouldGenerateUnionAccess(union U2 u) {
// CIR: cir.func{{.*}} @shouldGenerateUnionAccess(%[[ARG:.*]]: !rec_U2
// CIR-NEXT: %[[U:.*]] = cir.alloca !rec_U2, !cir.ptr<!rec_U2>, ["u", init] {alignment = 8 : i64}
// CIR-NEXT: cir.store{{.*}} %[[ARG]], %[[U]] : !rec_U2, !cir.ptr<!rec_U2>
-// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
-// CIR-NEXT: %[[ZERO_CHAR:.*]] = cir.cast integral %[[ZERO]] : !s32i -> !s8i
+// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s8i
// CIR-NEXT: %[[B_PTR:.*]] = cir.get_member %[[U]][0] {name = "b"} : !cir.ptr<!rec_U2> -> !cir.ptr<!s8i>
-// CIR-NEXT: cir.store{{.*}} %[[ZERO_CHAR]], %[[B_PTR]] : !s8i, !cir.ptr<!s8i>
+// CIR-NEXT: cir.store{{.*}} %[[ZERO]], %[[B_PTR]] : !s8i, !cir.ptr<!s8i>
// CIR-NEXT: %[[B_PTR2:.*]] = cir.get_member %[[U]][0] {name = "b"} : !cir.ptr<!rec_U2> -> !cir.ptr<!s8i>
// CIR-NEXT: %[[B_VAL:.*]] = cir.load{{.*}} %[[B_PTR2]] : !cir.ptr<!s8i>, !s8i
// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
@@ -173,12 +172,11 @@ void f3(union U3 u) {
// CIR: cir.func{{.*}} @f3(%[[ARG:.*]]: !rec_U3
// CIR-NEXT: %[[U:.*]] = cir.alloca !rec_U3, !cir.ptr<!rec_U3>, ["u", init] {alignment = 1 : i64}
// CIR-NEXT: cir.store{{.*}} %[[ARG]], %[[U]] : !rec_U3, !cir.ptr<!rec_U3>
-// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
-// CIR-NEXT: %[[ZERO_CHAR:.*]] = cir.cast integral %[[ZERO]] : !s32i -> !s8i
+// CIR-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0> : !s8i
// CIR-NEXT: %[[IDX:.*]] = cir.const #cir.int<2> : !s32i
// CIR-NEXT: %[[C_PTR:.*]] = cir.get_member %[[U]][0] {name = "c"} : !cir.ptr<!rec_U3> -> !cir.ptr<!cir.array<!s8i x 5>>
// CIR-NEXT: %[[ELEM_PTR:.*]] = cir.get_element %[[C_PTR]][%[[IDX]] : !s32i] : !cir.ptr<!cir.array<!s8i x 5>> -> !cir.ptr<!s8i>
-// CIR-NEXT: cir.store{{.*}} %[[ZERO_CHAR]], %[[ELEM_PTR]] : !s8i, !cir.ptr<!s8i>
+// CIR-NEXT: cir.store{{.*}} %[[ZERO]], %[[ELEM_PTR]] : !s8i, !cir.ptr<!s8i>
// CIR-NEXT: cir.return
// LLVM: define{{.*}} void @f3(%union.U3 %[[ARG:.*]])
@@ -203,12 +201,11 @@ void f5(union U4 u) {
// CIR: cir.func{{.*}} @f5(%[[ARG:.*]]: !rec_U4
// CIR-NEXT: %[[U:.*]] = cir.alloca !rec_U4, !cir.ptr<!rec_U4>, ["u", init] {alignment = 4 : i64}
// CIR-NEXT: cir.store{{.*}} %[[ARG]], %[[U]] : !rec_U4, !cir.ptr<!rec_U4>
-// CIR-NEXT: %[[CHAR_VAL:.*]] = cir.const #cir.int<65> : !s32i
-// CIR-NEXT: %[[CHAR_CAST:.*]] = cir.cast integral %[[CHAR_VAL]] : !s32i -> !s8i
+// CIR-NEXT: %[[CHAR_VAL:.*]] = cir.const #cir.int<65> : !s8i
// CIR-NEXT: %[[IDX:.*]] = cir.const #cir.int<4> : !s32i
// CIR-NEXT: %[[C_PTR:.*]] = cir.get_member %[[U]][0] {name = "c"} : !cir.ptr<!rec_U4> -> !cir.ptr<!cir.array<!s8i x 5>>
// CIR-NEXT: %[[ELEM_PTR:.*]] = cir.get_element %[[C_PTR]][%[[IDX]] : !s32i] : !cir.ptr<!cir.array<!s8i x 5>> -> !cir.ptr<!s8i>
-// CIR-NEXT: cir.store{{.*}} %[[CHAR_CAST]], %[[ELEM_PTR]] : !s8i, !cir.ptr<!s8i>
+// CIR-NEXT: cir.store{{.*}} %[[CHAR_VAL]], %[[ELEM_PTR]] : !s8i, !cir.ptr<!s8i>
// CIR-NEXT: cir.return
// LLVM: define{{.*}} void @f5(%union.U4 %[[ARG:.*]])
diff --git a/clang/test/CIR/CodeGen/vla.c b/clang/test/CIR/CodeGen/vla.c
index 0af4f838b6287..971a7def0db44 100644
--- a/clang/test/CIR/CodeGen/vla.c
+++ b/clang/test/CIR/CodeGen/vla.c
@@ -57,13 +57,12 @@ void f1(int len) {
// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]
// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]
-// CIR: %[[SIXTEEN:.*]] = cir.const #cir.int<16> : !s32i
-// CIR: %[[SIXTEEN_SIZE_T:.*]] = cir.cast integral %[[SIXTEEN]] : !s32i -> !u64i
+// CIR: %[[SIXTEEN:.*]] = cir.const #cir.int<16> : !u64i
// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i
// CIR: %[[STACK_PTR:.*]] = cir.stacksave
// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]
-// CIR: %[[TOTAL_LEN:.*]] = cir.binop(mul, %[[SIXTEEN_SIZE_T]], %[[LEN_SIZE_T]]) nuw
+// CIR: %[[TOTAL_LEN:.*]] = cir.binop(mul, %[[SIXTEEN]], %[[LEN_SIZE_T]]) nuw
// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN]] : !u64i, ["arr"]
// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]
// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index 9d5d5e67d6ad9..47d101e79ec15 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -545,7 +545,6 @@ __m512i test_mm512_mask_i32gather_epi64(__m512i __v1_old, __mmask8 __mask, __m25
__m512i test_mm512_ror_epi32(__m512i __A) {
// CIR-LABEL: test_mm512_ror_epi32
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
// CIR: cir.vec.splat %{{.*}} : !u32i, !cir.vector<16 x !u32i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s32i>, !cir.vector<16 x !u32i>) -> !cir.vector<16 x !s32i>
@@ -561,8 +560,6 @@ __m512i test_mm512_ror_epi32(__m512i __A) {
__m512i test_mm512_ror_epi64(__m512i __A) {
// CIR-LABEL: test_mm512_ror_epi64
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
- // CIR: cir.cast integral %{{.*}} : !u32i -> !u64i
// CIR: cir.vec.splat %{{.*}} : !u64i, !cir.vector<8 x !u64i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<8 x !s64i>, !cir.vector<8 x !s64i>, !cir.vector<8 x !u64i>) -> !cir.vector<8 x !s64i>
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512vl-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512vl-builtins.c
index 4a1fad1336e90..d61d1a5be7dc0 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512vl-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512vl-builtins.c
@@ -201,7 +201,6 @@ __m256i test_mm256_mask_i32gather_epi32(__m256i __v1_old, __mmask8 __mask, __m25
__m128i test_mm_ror_epi32(__m128i __A) {
// CIR-LABEL: test_mm_ror_epi32
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
// CIR: cir.vec.splat %{{.*}} : !u32i, !cir.vector<4 x !u32i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !s32i>
@@ -217,7 +216,6 @@ __m128i test_mm_ror_epi32(__m128i __A) {
__m256i test_mm256_ror_epi32(__m256i __A) {
// CIR-LABEL: test_mm256_ror_epi32
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
// CIR: cir.vec.splat %{{.*}} : !u32i, !cir.vector<8 x !u32i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<8 x !s32i>, !cir.vector<8 x !s32i>, !cir.vector<8 x !u32i>) -> !cir.vector<8 x !s32i>
@@ -233,8 +231,6 @@ __m256i test_mm256_ror_epi32(__m256i __A) {
__m128i test_mm_ror_epi64(__m128i __A) {
// CIR-LABEL: test_mm_ror_epi64
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
- // CIR: cir.cast integral %{{.*}} : !u32i -> !u64i
// CIR: cir.vec.splat %{{.*}} : !u64i, !cir.vector<2 x !u64i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !u64i>) -> !cir.vector<2 x !s64i>
@@ -248,8 +244,6 @@ __m128i test_mm_ror_epi64(__m128i __A) {
__m256i test_mm256_ror_epi64(__m256i __A) {
// CIR-LABEL: test_mm256_ror_epi64
- // CIR: cir.cast integral %{{.*}} : !s32i -> !u32i
- // CIR: cir.cast integral %{{.*}} : !u32i -> !u64i
// CIR: cir.vec.splat %{{.*}} : !u64i, !cir.vector<4 x !u64i>
// CIR: cir.call_llvm_intrinsic "fshr" %{{.*}}: (!cir.vector<4 x !s64i>, !cir.vector<4 x !s64i>, !cir.vector<4 x !u64i>) -> !cir.vector<4 x !s64i>
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/xop-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/xop-builtins.c
index 88ccf29862848..5a5ba4c086f36 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/xop-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/xop-builtins.c
@@ -45,7 +45,6 @@ __m128i test_mm_roti_epi8(__m128i a) {
__m128i test_mm_roti_epi16(__m128i a) {
// CIR-LABEL: test_mm_roti_epi16
- // CIR: cir.cast integral %{{.*}} : !u8i -> !u16i
// CIR: cir.vec.splat %{{.*}} : !{{[us]}}16i, !cir.vector<8 x !u16i>
// CIR: cir.call_llvm_intrinsic "fshl" %{{.*}} : (!cir.vector<8 x !{{[su]}}16i>, !cir.vector<8 x !{{[su]}}16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !{{[su]}}16i>
@@ -61,7 +60,6 @@ __m128i test_mm_roti_epi16(__m128i a) {
__m128i test_mm_roti_epi32(__m128i a) {
// CIR-LABEL: test_mm_roti_epi32
- // CIR: cir.cast integral %{{.*}} : !u8i -> !u32i
// CIR: cir.vec.splat %{{.*}} : !{{[us]}}32i, !cir.vector<4 x !u32i>
// CIR: cir.call_llvm_intrinsic "fshl" %{{.*}} : (!cir.vector<4 x !{{[su]}}32i>, !cir.vector<4 x !{{[su]}}32i>, !cir.vector<4 x !u32i>) -> !cir.vector<4 x !{{[su]}}32i>
@@ -77,7 +75,6 @@ __m128i test_mm_roti_epi32(__m128i a) {
__m128i test_mm_roti_epi64(__m128i a) {
// CIR-LABEL: test_mm_roti_epi64
- // CIR: cir.cast integral %{{.*}} : !u8i -> !u64i
// CIR: cir.vec.splat %{{.*}} : !u64i, !cir.vector<2 x !u64i>
// CIR: cir.call_llvm_intrinsic "fshl" %{{.*}} : (!cir.vector<2 x !{{[su]}}64i>, !cir.vector<2 x !{{[su]}}64i>, !cir.vector<2 x !u64i>) -> !cir.vector<2 x !s64i>
diff --git a/clang/test/CIR/Transforms/canonicalize.cir b/clang/test/CIR/Transforms/canonicalize.cir
index de7c90f716398..4f29fbc273801 100644
--- a/clang/test/CIR/Transforms/canonicalize.cir
+++ b/clang/test/CIR/Transforms/canonicalize.cir
@@ -1,8 +1,11 @@
// RUN: cir-opt %s -cir-canonicalize -o - | FileCheck %s
+!s8i = !cir.int<s, 8>
!s32i = !cir.int<s, 32>
!s64i = !cir.int<s, 64>
+!u8i = !cir.int<u, 8>
!u32i = !cir.int<u, 32>
+!u64i = !cir.int<u, 64>
module {
cir.func @redundant_br() {
@@ -116,4 +119,106 @@ module {
// CHECK-NEXT: cir.return %[[P]] : !s64i
// CHECK-NEXT: }
+ cir.func @cast_s32_s64() -> !s64i {
+ %0 = cir.const #cir.int<2> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !s64i
+ cir.return %1 : !s64i
+ }
+ // CHECK: @cast_s32_s64()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<2> : !s64i
+ // CHECK-NEXT: cir.return %[[P]] : !s64i
+ // CHECK-NEXT: }
+
+ cir.func @cast_s64_s32() -> !s32i {
+ %0 = cir.const #cir.int<2> : !s64i
+ %1 = cir.cast integral %0 : !s64i -> !s32i
+ cir.return %1 : !s32i
+ }
+ // CHECK: @cast_s64_s32()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<2> : !s32i
+ // CHECK-NEXT: cir.return %[[P]] : !s32i
+ // CHECK-NEXT: }
+
+ cir.func @cast_s32_u32() -> !u32i {
+ %0 = cir.const #cir.int<2> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !u32i
+ cir.return %1 : !u32i
+ }
+ // CHECK: @cast_s32_u32()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<2> : !u32i
+ // CHECK-NEXT: cir.return %[[P]] : !u32i
+ // CHECK-NEXT: }
+
+ cir.func @cast_u32_s32() -> !s32i {
+ %0 = cir.const #cir.int<2> : !u32i
+ %1 = cir.cast integral %0 : !u32i -> !s32i
+ cir.return %1 : !s32i
+ }
+ // CHECK: @cast_u32_s32()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<2> : !s32i
+ // CHECK-NEXT: cir.return %[[P]] : !s32i
+ // CHECK-NEXT: }
+
+ cir.func @cast_overflow() -> !s8i {
+ %0 = cir.const #cir.int<259> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !s8i
+ cir.return %1 : !s8i
+ }
+ // CHECK: @cast_overflow()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<3> : !s8i
+ // CHECK-NEXT: cir.return %[[P]] : !s8i
+ // CHECK-NEXT: }
+
+ cir.func @cast_sext_s32_s64() -> !s64i {
+ %0 = cir.const #cir.int<-1> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !s64i
+ cir.return %1 : !s64i
+ }
+ // CHECK: @cast_sext_s32_s64()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<-1> : !s64i
+ // CHECK-NEXT: cir.return %[[P]] : !s64i
+ // CHECK-NEXT: }
+
+ cir.func @cast_sext_s32_u64() -> !u64i {
+ %0 = cir.const #cir.int<-1> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !u64i
+ cir.return %1 : !u64i
+ }
+ // CHECK: @cast_sext_s32_u64()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<18446744073709551615> : !u64i
+ // CHECK-NEXT: cir.return %[[P]] : !u64i
+ // CHECK-NEXT: }
+
+ cir.func @cast_sext_twostep_s32_u64() -> !u64i {
+ %0 = cir.const #cir.int<-1> : !s32i
+ %1 = cir.cast integral %0 : !s32i -> !s64i
+ %2 = cir.cast integral %1 : !s64i -> !u64i
+ cir.return %2 : !u64i
+ }
+
+ // CHECK: @cast_sext_twostep_s32_u64()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<18446744073709551615> : !u64i
+ // CHECK-NEXT: cir.return %[[P]] : !u64i
+ // CHECK-NEXT: }
+
+ cir.func @cast_zext_u8_u32() -> !u32i {
+ %0 = cir.const #cir.int<255> : !u8i
+ %1 = cir.cast integral %0 : !u8i -> !u32i
+ cir.return %1 : !u32i
+ }
+ // CHECK: @cast_zext_u8_u32()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<255> : !u32i
+ // CHECK-NEXT: cir.return %[[P]] : !u32i
+ // CHECK-NEXT: }
+
+ cir.func @cast_zext_u8_s32() -> !s32i {
+ %0 = cir.const #cir.int<255> : !u8i
+ %1 = cir.cast integral %0 : !u8i -> !s32i
+ cir.return %1 : !s32i
+ }
+ // CHECK: @cast_zext_u8_s32()
+ // CHECK-NEXT: %[[P:.+]] = cir.const #cir.int<255> : !s32i
+ // CHECK-NEXT: cir.return %[[P]] : !s32i
+ // CHECK-NEXT: }
+
}
diff --git a/clang/test/CIR/Transforms/switch.cir b/clang/test/CIR/Transforms/switch.cir
index 3addfe37061cd..61877ed1b4565 100644
--- a/clang/test/CIR/Transforms/switch.cir
+++ b/clang/test/CIR/Transforms/switch.cir
@@ -258,12 +258,11 @@ module {
// CHECK-NEXT: cir.store
// CHECK-NEXT: cir.br ^[[EPILOG]]
// CHECK-NEXT: ^[[JUDGE_RANGE]]:
-// CHECK-NEXT: %[[RANGE:[0-9]+]] = cir.const #cir.int<99>
// CHECK-NEXT: %[[LOWER_BOUND:[0-9]+]] = cir.const #cir.int<1>
// CHECK-NEXT: %[[DIFF:[0-9]+]] = cir.binop(sub, %[[X]], %[[LOWER_BOUND]])
// CHECK-NEXT: %[[U_DIFF:[0-9]+]] = cir.cast integral %[[DIFF]] : !s32i -> !u32i
-// CHECK-NEXT: %[[U_RANGE:[0-9]+]] = cir.cast integral %[[RANGE]] : !s32i -> !u32i
-// CHECK-NEXT: %[[CMP_RESULT:[0-9]+]] = cir.cmp(le, %[[U_DIFF]], %[[U_RANGE]])
+// CHECK-NEXT: %[[RANGE:[0-9]+]] = cir.const #cir.int<99>
+// CHECK-NEXT: %[[CMP_RESULT:[0-9]+]] = cir.cmp(le, %[[U_DIFF]], %[[RANGE]])
// CHECK-NEXT: cir.brcond %[[CMP_RESULT]] ^[[CASE_RANGE]], ^[[CASE_DEFAULT:bb[0-9]+]]
// CHECK-NEXT: ^[[CASE_DEFAULT]]:
// CHECK-NEXT: cir.int<3>
@@ -301,13 +300,12 @@ module {
// CHECK: ^bb[[#DEFAULT_BB]]: // 2 preds: ^bb[[#NO_PRED_BB]], ^bb[[#RANGE_BR]]
// CHECK: cir.br ^bb[[#EXIT:]]
// CHECK: ^bb[[#RANGE_BR]]: // pred: ^bb[[#BB2:]]
-// CHECK: %[[CONST97:.*]] = cir.const #cir.int<97> : !s32i
// CHECK: %[[CONST3:.*]] = cir.const #cir.int<3> : !s32i
// CHECK: %[[SUB:.*]] = cir.binop(sub, %[[COND]], %[[CONST3]]) : !s32i
// CHECK: %[[CAST1:.*]] = cir.cast integral %[[SUB]] : !s32i -> !u32i
-// CHECK: %[[CAST2:.*]] = cir.cast integral %[[CONST97]] : !s32i -> !u32i
-// CHECK: %[[CMP:.*]] = cir.cmp(le, %[[CAST1]], %[[CAST2]]) : !u32i, !cir.bool
-// CHECK: cir.brcond %7 ^bb[[#DEFAULT_BB]], ^bb[[#RANGE_BB:]]
+// CHECK: %[[CONST97:.*]] = cir.const #cir.int<97> : !u32i
+// CHECK: %[[CMP:.*]] = cir.cmp(le, %[[CAST1]], %[[CONST97]]) : !u32i, !cir.bool
+// CHECK: cir.brcond %[[CMP]] ^bb[[#DEFAULT_BB]], ^bb[[#RANGE_BB:]]
// CHECK: ^bb[[#RANGE_BB]]: // pred: ^bb[[#RANGE_BR]]
// CHECK: cir.br ^bb[[#EXIT]]
// CHECK: ^bb[[#EXIT]]: // 2 preds: ^bb[[#DEFAULT_BB]], ^bb[[#RANGE_BB]]
More information about the cfe-commits
mailing list