Skip to content

Commit e8e3270

Browse files
committed
- Correctly emit dummy value for floating casts
- Emit dummy value and a diagnostic during LLVM lowering for int_to_bool casts - Expand tests to cover LLVM lowering
1 parent 6de0b88 commit e8e3270

File tree

3 files changed

+59
-32
lines changed

3 files changed

+59
-32
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
207207
castKind = cir::CastKind::float_to_int;
208208
} else if (mlir::isa<cir::CIRFPTypeInterface>(dstTy)) {
209209
cgf.getCIRGenModule().errorNYI("floating point casts");
210-
return builder.getNullPtr(dstTy, src.getLoc());
210+
return cgf.createDummyValue(src.getLoc(), dstType);
211211
} else {
212212
llvm_unreachable("Internal error: Cast to unexpected type");
213213
}

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,15 @@ mlir::LogicalResult CIRToLLVMCastOpLowering::matchAndRewrite(
303303
castOp, targetType, elementTy, sourceValue, offset);
304304
break;
305305
}
306-
case cir::CastKind::int_to_bool:
306+
case cir::CastKind::int_to_bool: {
307307
assert(!cir::MissingFeatures::opCmp());
308-
break;
308+
mlir::Type dstType = castOp.getResult().getType();
309+
mlir::Type llvmDstType = getTypeConverter()->convertType(dstType);
310+
auto zeroBool = rewriter.create<mlir::LLVM::ConstantOp>(
311+
castOp.getLoc(), llvmDstType, mlir::BoolAttr::get(getContext(), false));
312+
rewriter.replaceOp(castOp, zeroBool);
313+
return castOp.emitError() << "NYI int_to_bool cast";
314+
}
309315
case cir::CastKind::integral: {
310316
mlir::Type srcType = castOp.getSrc().getType();
311317
mlir::Type dstType = castOp.getResult().getType();

clang/test/CIR/CodeGen/cast.cpp

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,89 @@
1-
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2-
// RUN: FileCheck --input-file=%t.cir %s
1+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -DCIR_ONLY %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
35

46
unsigned char cxxstaticcast_0(unsigned int x) {
57
return static_cast<unsigned char>(x);
68
}
79

8-
// CHECK: cir.func @cxxstaticcast_0
9-
// CHECK: %0 = cir.alloca !cir.int<u, 32>, !cir.ptr<!cir.int<u, 32>>, ["x", init] {alignment = 4 : i64}
10-
// CHECK: cir.store %arg0, %0 : !cir.int<u, 32>, !cir.ptr<!cir.int<u, 32>>
11-
// CHECK: %1 = cir.load %0 : !cir.ptr<!cir.int<u, 32>>, !cir.int<u, 32>
12-
// CHECK: %2 = cir.cast(integral, %1 : !cir.int<u, 32>), !cir.int<u, 8>
13-
// CHECK: cir.return %2 : !cir.int<u, 8>
14-
// CHECK: }
10+
// CIR: cir.func @cxxstaticcast_0
11+
// CIR: %0 = cir.alloca !cir.int<u, 32>, !cir.ptr<!cir.int<u, 32>>, ["x", init] {alignment = 4 : i64}
12+
// CIR: cir.store %arg0, %0 : !cir.int<u, 32>, !cir.ptr<!cir.int<u, 32>>
13+
// CIR: %1 = cir.load %0 : !cir.ptr<!cir.int<u, 32>>, !cir.int<u, 32>
14+
// CIR: %2 = cir.cast(integral, %1 : !cir.int<u, 32>), !cir.int<u, 8>
15+
// CIR: cir.return %2 : !cir.int<u, 8>
16+
// CIR: }
17+
18+
// LLVM: define i8 @cxxstaticcast_0(i32 %0)
19+
// LLVM: %[[LOAD:[0-9]+]] = load i32, ptr %{{[0-9]+}}, align 4
20+
// LLVM: %[[TRUNC:[0-9]+]] = trunc i32 %[[LOAD]] to i8
21+
// LLVM: ret i8 %[[TRUNC]]
1522

1623

1724
int cStyleCasts_0(unsigned x1, int x2, float x3, short x4, double x5) {
18-
// CHECK: cir.func @cStyleCasts_0
25+
// CIR: cir.func @cStyleCasts_0
26+
// LLVM: define i32 @cStyleCasts_0
1927

2028
char a = (char)x1; // truncate
21-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 8>
29+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 8>
30+
// LLVM: %{{[0-9]+}} = trunc i32 %{{[0-9]+}} to i8
2231

2332
short b = (short)x2; // truncate with sign
24-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<s, 16>
33+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<s, 16>
34+
// LLVM: %{{[0-9]+}} = trunc i32 %{{[0-9]+}} to i16
2535

2636
long long c = (long long)x1; // zero extend
27-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 64>
37+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 64>
38+
// LLVM: %{{[0-9]+}} = zext i32 %{{[0-9]+}} to i64
2839

2940
long long d = (long long)x2; // sign extend
30-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<s, 64>
41+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<s, 64>
42+
// LLVM: %{{[0-9]+}} = sext i32 %{{[0-9]+}} to i64
3143

3244
unsigned ui = (unsigned)x2; // sign drop
33-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<u, 32>
45+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<s, 32>), !cir.int<u, 32>
3446

3547
int si = (int)x1; // sign add
36-
// CHECK: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 32>
48+
// CIR: %{{[0-9]+}} = cir.cast(integral, %{{[0-9]+}} : !cir.int<u, 32>), !cir.int<s, 32>
3749

3850
bool ib;
3951
int bi = (int)ib; // bool to int
40-
// CHECK: %{{[0-9]+}} = cir.cast(bool_to_int, %{{[0-9]+}} : !cir.bool), !cir.int<s, 32>
52+
// CIR: %{{[0-9]+}} = cir.cast(bool_to_int, %{{[0-9]+}} : !cir.bool), !cir.int<s, 32>
53+
// LLVM: %{{[0-9]+}} = zext i1 %{{[0-9]+}} to i32
4154

55+
#ifdef CIR_ONLY
4256
bool b2 = x2; // int to bool
43-
// CHECK: %{{[0-9]+}} = cir.cast(int_to_bool, %{{[0-9]+}} : !cir.int<s, 32>), !cir.bool
44-
57+
// CIR: %{{[0-9]+}} = cir.cast(int_to_bool, %{{[0-9]+}} : !cir.int<s, 32>), !cir.bool
58+
#endif
59+
60+
#ifdef CIR_ONLY
4561
void *p;
46-
bool b3 = p; // ptr to bool
47-
// CHECK: %{{[0-9]+}} = cir.cast(ptr_to_bool, %{{[0-9]+}} : !cir.ptr<!cir.void>), !cir.bool
62+
bool b3 = p; // ptr to bool
63+
// CIR: %{{[0-9]+}} = cir.cast(ptr_to_bool, %{{[0-9]+}} : !cir.ptr<!cir.void>), !cir.bool
64+
#endif
4865

4966
float f;
5067
bool b4 = f; // float to bool
51-
// CHECK: %{{[0-9]+}} = cir.cast(float_to_bool, %{{[0-9]+}} : !cir.float), !cir.bool
68+
// CIR: %{{[0-9]+}} = cir.cast(float_to_bool, %{{[0-9]+}} : !cir.float), !cir.bool
69+
// LLVM: %{{[0-9]+}} = fcmp une float %{{[0-9]+}}, 0.000000e+00
70+
// LLVM: %{{[0-9]+}} = zext i1 %{{[0-9]+}} to i8
5271

5372
return 0;
5473
}
5574

75+
#ifdef CIR_ONLY
5676
bool cptr(void *d) {
5777
bool x = d;
5878
return x;
5979
}
6080

61-
// CHECK: cir.func @cptr(%arg0: !cir.ptr<!cir.void>
62-
// CHECK: %0 = cir.alloca !cir.ptr<!cir.void>, !cir.ptr<!cir.ptr<!cir.void>>, ["d", init] {alignment = 8 : i64}
81+
// CIR: cir.func @cptr(%arg0: !cir.ptr<!cir.void>
82+
// CIR: %0 = cir.alloca !cir.ptr<!cir.void>, !cir.ptr<!cir.ptr<!cir.void>>, ["d", init] {alignment = 8 : i64}
6383

64-
// CHECK: %2 = cir.load %0 : !cir.ptr<!cir.ptr<!cir.void>>, !cir.ptr<!cir.void>
65-
// CHECK: %3 = cir.cast(ptr_to_bool, %2 : !cir.ptr<!cir.void>), !cir.bool
84+
// CIR: %2 = cir.load %0 : !cir.ptr<!cir.ptr<!cir.void>>, !cir.ptr<!cir.void>
85+
// CIR: %3 = cir.cast(ptr_to_bool, %2 : !cir.ptr<!cir.void>), !cir.bool
86+
#endif
6687

6788
void should_not_cast() {
6889
unsigned x1;
@@ -74,6 +95,6 @@ void should_not_cast() {
7495
(void) ib; // void cast
7596
}
7697

77-
// CHECK: cir.func @should_not_cast
78-
// CHECK-NOT: cir.cast
79-
// CHECK: cir.return
98+
// CIR: cir.func @should_not_cast
99+
// CIR-NOT: cir.cast
100+
// CIR: cir.return

0 commit comments

Comments
 (0)