https://github.com/andykaylor created https://github.com/llvm/llvm-project/pull/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. >From a888f338086e6356b2c113d6ef7d77225a3f9462 Mon Sep 17 00:00:00 2001 From: Andy Kaylor <[email protected]> Date: Wed, 7 Jan 2026 10:34:17 -0800 Subject: [PATCH] [CIR] Implement simple folding for integer casts 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. --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 33 +++++- .../CIR/CodeGen/aapcs-volatile-bitfields.c | 15 +-- clang/test/CIR/CodeGen/assign-operator.cpp | 5 +- clang/test/CIR/CodeGen/binassign.c | 3 +- clang/test/CIR/CodeGen/comma.c | 3 +- clang/test/CIR/CodeGen/cxx-default-init.cpp | 5 +- clang/test/CIR/CodeGen/enum.cpp | 4 +- .../CIR/CodeGen/finegrain-bitfield-access.cpp | 25 ++--- clang/test/CIR/CodeGen/struct.cpp | 5 +- clang/test/CIR/CodeGen/union.c | 15 +-- clang/test/CIR/CodeGen/vla.c | 5 +- .../CodeGenBuiltins/X86/avx512f-builtins.c | 3 - .../CodeGenBuiltins/X86/avx512vl-builtins.c | 6 - .../CIR/CodeGenBuiltins/X86/xop-builtins.c | 3 - clang/test/CIR/Transforms/canonicalize.cir | 105 ++++++++++++++++++ clang/test/CIR/Transforms/switch.cir | 12 +- 16 files changed, 174 insertions(+), 73 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 8f0dc705181e6..495448fca24a7 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 differences, 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]] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
