Skip to content

Commit 2409769

Browse files
authored
[CIR][Lowering] fixes return value for = operator for bitfields (#1247)
Basically that is - the return value for `=` operator for bitfield assignment is wrong now. For example, the next function returns `7` for 3 bit bit field, though it should be `-1`: ``` int get_a(T *t) { return (t->a = 7); } ``` This PR fix it. Actually, the bug was in the lowering - the integer cast is applied in the wrong place (in comparison with the original codegen).
1 parent 232db8c commit 2409769

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,9 +3650,6 @@ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite(
36503650

36513651
auto resultTy = getTypeConverter()->convertType(op.getType());
36523652

3653-
resultVal = createIntCast(rewriter, resultVal,
3654-
mlir::cast<mlir::IntegerType>(resultTy));
3655-
36563653
if (info.getIsSigned()) {
36573654
assert(size <= storageSize);
36583655
unsigned highBits = storageSize - size;
@@ -3663,6 +3660,10 @@ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite(
36633660
}
36643661
}
36653662

3663+
resultVal = createIntCast(rewriter, resultVal,
3664+
mlir::cast<mlir::IntegerType>(resultTy),
3665+
info.getIsSigned());
3666+
36663667
rewriter.replaceOp(op, resultVal);
36673668
return mlir::success();
36683669
}

clang/test/CIR/CodeGen/bitfields.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
22
// RUN: FileCheck --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
35

46
struct __long {
57
struct __attribute__((__packed__)) {
@@ -131,6 +133,16 @@ void createD() {
131133
D d = {1,2,3};
132134
}
133135

136+
// check the -1 is stored to the ret value
137+
// LLVM: define dso_local i32 {{@.*get_a.*}}
138+
// LLVM: %[[V1:.*]] = alloca i32
139+
// LLVM: store i32 -1, ptr %[[V1]], align 4
140+
// LLVM: %[[V2:.*]] = load i32, ptr %[[V1]], align 4
141+
// LLVM: ret i32 %[[V2:.*]]
142+
int get_a(T *t) {
143+
return (t->a = 7);
144+
}
145+
134146
typedef struct {
135147
int x : 15;
136148
int y ;

0 commit comments

Comments
 (0)