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

Reply via email to