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]] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
