https://github.com/banach-space updated https://github.com/llvm/llvm-project/pull/200005
From 2dce02ee265ed058c03dd763b3138d3c8589ae5b Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Wed, 27 May 2026 15:29:07 +0000 Subject: [PATCH 1/4] [cir] Refine cir::CastOp semantics for int <-> float casts Int-to-float and float-to-int casts in cir::CastOp are lowered directly to their LLVM equivalents. Update the verifier to reflect this semantics and ensure that, for vector casts, the source and destination vectors have the same length. This lets the CIR verifier reject invalid casts earlier, instead of relying on errors reported later at the LLVM IR level. --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 18 ++++++++++++++---- clang/test/CIR/IR/invalid-cast.cir | 12 ++++++++++++ clang/test/CIR/Lowering/cast.cir | 4 +++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 46b3cd5a47935..d44a0971f30e9 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -526,12 +526,22 @@ LogicalResult cir::CastOp::verify() { "address space of the operand"; } - if (mlir::isa<cir::VectorType>(srcType) && - mlir::isa<cir::VectorType>(resType)) { + auto kind = getKind(); + auto srcVTy = mlir::dyn_cast<cir::VectorType>(srcType); + auto resVTy = mlir::dyn_cast<cir::VectorType>(resType); + if (srcVTy && resVTy) { + if ((kind == cir::CastKind::int_to_float || + kind == cir::CastKind::float_to_int) && + srcVTy.getSize() != resVTy.getSize()) { + return emitOpError() + << "vector float-to-int and int-to-float casts require " + "source and destination vectors to have the same number of " + "elements"; + } // Use the element type of the vector to verify the cast kind. (Except for // bitcast, see below.) - srcType = mlir::dyn_cast<cir::VectorType>(srcType).getElementType(); - resType = mlir::dyn_cast<cir::VectorType>(resType).getElementType(); + srcType = srcVTy.getElementType(); + resType = resVTy.getElementType(); } switch (getKind()) { diff --git a/clang/test/CIR/IR/invalid-cast.cir b/clang/test/CIR/IR/invalid-cast.cir index 321934215e84d..0477db1616266 100644 --- a/clang/test/CIR/IR/invalid-cast.cir +++ b/clang/test/CIR/IR/invalid-cast.cir @@ -25,3 +25,15 @@ module { cir.return %0 : !cir.bool } } + +// ----- + +!s8i = !cir.int<s, 8> + +module { + cir.func @int_to_float(%in: !cir.vector<8 x !s8i>) { + // expected-error@+1 {{vector float-to-int and int-to-float casts require source and destination vectors to have the same number of elements}} + cir.cast int_to_float %in : !cir.vector<8 x !s8i> -> !cir.vector<2 x !cir.float> + cir.return + } +} diff --git a/clang/test/CIR/Lowering/cast.cir b/clang/test/CIR/Lowering/cast.cir index ec104edec2405..b3706d79ffab9 100644 --- a/clang/test/CIR/Lowering/cast.cir +++ b/clang/test/CIR/Lowering/cast.cir @@ -10,7 +10,7 @@ !u64i = !cir.int<u, 64> module { - cir.func @cStyleCasts(%arg0: !u32i, %arg1: !s32i, %arg2: !cir.float, %arg3: !cir.double) -> !s32i { + cir.func @cStyleCasts(%arg0: !u32i, %arg1: !s32i, %arg2: !cir.float, %arg3: !cir.double, %arg4: !cir.vector<2 x !s32i>) -> !s32i { // CHECK: llvm.func @cStyleCasts %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["x1", init] {alignment = 4 : i64} %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x2", init] {alignment = 4 : i64} @@ -62,6 +62,8 @@ module { // Floating point casts. %25 = cir.cast int_to_float %arg1 : !s32i -> !cir.float // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : i32 to f32 + %251 = cir.cast int_to_float %arg4 : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float> + // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : vector<2xi32> to vector<2xf32> %26 = cir.cast int_to_float %arg0 : !u32i -> !cir.float // CHECK: %{{.+}} = llvm.uitofp %{{.+}} : i32 to f32 %27 = cir.cast float_to_int %arg2 : !cir.float -> !s32i From 7f57e430a1ca939d4fc626800b17d14b6797c6d2 Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Fri, 29 May 2026 17:04:31 +0000 Subject: [PATCH 2/4] Add a test for bitcast with vectors --- clang/test/CIR/Lowering/cast.cir | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/CIR/Lowering/cast.cir b/clang/test/CIR/Lowering/cast.cir index b3706d79ffab9..f22cb76480776 100644 --- a/clang/test/CIR/Lowering/cast.cir +++ b/clang/test/CIR/Lowering/cast.cir @@ -64,6 +64,8 @@ module { // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : i32 to f32 %251 = cir.cast int_to_float %arg4 : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float> // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : vector<2xi32> to vector<2xf32> + %252 = cir.cast bitcast %arg4 : !cir.vector<2 x !s32i> -> !cir.vector<1 x !cir.double> + // CHECK: %{{.+}} = llvm.bitcast %{{.+}} : vector<2xi32> to vector<1xf64> %26 = cir.cast int_to_float %arg0 : !u32i -> !cir.float // CHECK: %{{.+}} = llvm.uitofp %{{.+}} : i32 to f32 %27 = cir.cast float_to_int %arg2 : !cir.float -> !s32i From 95b7ce3482411fd795d2ea89d3ffba05e761fe9e Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Fri, 29 May 2026 17:08:54 +0000 Subject: [PATCH 3/4] Move tests from @cStyleCasts to @vectorCasts --- clang/test/CIR/Lowering/cast.cir | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/clang/test/CIR/Lowering/cast.cir b/clang/test/CIR/Lowering/cast.cir index f22cb76480776..2fc47dbb0a6a6 100644 --- a/clang/test/CIR/Lowering/cast.cir +++ b/clang/test/CIR/Lowering/cast.cir @@ -62,10 +62,6 @@ module { // Floating point casts. %25 = cir.cast int_to_float %arg1 : !s32i -> !cir.float // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : i32 to f32 - %251 = cir.cast int_to_float %arg4 : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float> - // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : vector<2xi32> to vector<2xf32> - %252 = cir.cast bitcast %arg4 : !cir.vector<2 x !s32i> -> !cir.vector<1 x !cir.double> - // CHECK: %{{.+}} = llvm.bitcast %{{.+}} : vector<2xi32> to vector<1xf64> %26 = cir.cast int_to_float %arg0 : !u32i -> !cir.float // CHECK: %{{.+}} = llvm.uitofp %{{.+}} : i32 to f32 %27 = cir.cast float_to_int %arg2 : !cir.float -> !s32i @@ -96,4 +92,13 @@ module { cir.store %3, %1 : !u8i, !cir.ptr<!u8i> cir.return } + + cir.func @vectorCasts(%arg0:!cir.vector<2 x !s32i>) { + %i_2_f = cir.cast int_to_float %arg0 : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float> + // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : vector<2xi32> to vector<2xf32> + %bitcast = cir.cast bitcast %arg0 : !cir.vector<2 x !s32i> -> !cir.vector<1 x !cir.double> + // CHECK: %{{.+}} = llvm.bitcast %{{.+}} : vector<2xi32> to vector<1xf64> + + cir.return + } } From 942362488a30073bc71b6015edeeb06d0dcb4117 Mon Sep 17 00:00:00 2001 From: Andrzej Warzynski <[email protected]> Date: Fri, 29 May 2026 17:47:03 +0000 Subject: [PATCH 4/4] Address comments from Andy --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 2 +- clang/test/CIR/Lowering/cast.cir | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index d44a0971f30e9..0a3afe4bd1f0d 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -526,7 +526,7 @@ LogicalResult cir::CastOp::verify() { "address space of the operand"; } - auto kind = getKind(); + cir::CastKind kind = getKind(); auto srcVTy = mlir::dyn_cast<cir::VectorType>(srcType); auto resVTy = mlir::dyn_cast<cir::VectorType>(resType); if (srcVTy && resVTy) { diff --git a/clang/test/CIR/Lowering/cast.cir b/clang/test/CIR/Lowering/cast.cir index 2fc47dbb0a6a6..19ed51e14519f 100644 --- a/clang/test/CIR/Lowering/cast.cir +++ b/clang/test/CIR/Lowering/cast.cir @@ -10,7 +10,7 @@ !u64i = !cir.int<u, 64> module { - cir.func @cStyleCasts(%arg0: !u32i, %arg1: !s32i, %arg2: !cir.float, %arg3: !cir.double, %arg4: !cir.vector<2 x !s32i>) -> !s32i { + cir.func @cStyleCasts(%arg0: !u32i, %arg1: !s32i, %arg2: !cir.float, %arg3: !cir.double) -> !s32i { // CHECK: llvm.func @cStyleCasts %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["x1", init] {alignment = 4 : i64} %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x2", init] {alignment = 4 : i64} @@ -93,9 +93,11 @@ module { cir.return } - cir.func @vectorCasts(%arg0:!cir.vector<2 x !s32i>) { + cir.func @vectorCasts(%arg0: !cir.vector<2 x !s32i>, %arg1: !cir.vector<4 x !cir.float>) { %i_2_f = cir.cast int_to_float %arg0 : !cir.vector<2 x !s32i> -> !cir.vector<2 x !cir.float> // CHECK: %{{.+}} = llvm.sitofp %{{.+}} : vector<2xi32> to vector<2xf32> + %f_2_1 = cir.cast float_to_int %arg1 : !cir.vector<4 x !cir.float> -> !cir.vector<4 x !s32i> + // CHECK: %{{.+}} = llvm.fptosi %{{.+}} : vector<4xf32> to vector<4xi32> %bitcast = cir.cast bitcast %arg0 : !cir.vector<2 x !s32i> -> !cir.vector<1 x !cir.double> // CHECK: %{{.+}} = llvm.bitcast %{{.+}} : vector<2xi32> to vector<1xf64> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
