Skip to content

Commit 60a2795

Browse files
authored
[Clang][CodeGen] Use EmitLoadOfLValue instead of EmitLoadOfScalar to get LHS for complex compound assignment (#166798)
- Fixes #166512 - `ComplexExprEmitter::EmitCompoundAssignLValue` is calling `EmitLoadOfScalar(LValue, SourceLocation)` to load the LHS value in the case that it's non-complex, however this function requires that the value is a simple LValue - issue occurred because the LValue in question was a bitfield LValue. I changed it to use this function which seems to handle all of the different cases (deferring to the original `EmitLoadOfScalar` if it's a simple LValue)
1 parent fb8155c commit 60a2795

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ Bug Fixes in This Version
484484
- Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951)
485485
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
486486
- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
487+
- Fix a bug leading to incorrect code generation with complex number compound assignment and bitfield values, which also caused a crash with UBsan. (#GH166798)
487488
- Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731)
488489

489490
Bug Fixes to Compiler Builtins

clang/lib/CodeGen/CGExprComplex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
12831283
else
12841284
OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
12851285
} else {
1286-
llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc);
1286+
llvm::Value *LHSVal = CGF.EmitLoadOfLValue(LHS, Loc).getScalarVal();
12871287
// For floating point real operands we can directly pass the scalar form
12881288
// to the binary operator emission and potentially get more efficient code.
12891289
if (LHSTy->isRealFloatingType()) {
@@ -1318,7 +1318,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
13181318
} else {
13191319
llvm::Value *ResVal =
13201320
CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc);
1321-
CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
1321+
CGF.EmitStoreThroughLValue(RValue::get(ResVal), LHS, /*isInit*/ false);
13221322
Val = RValue::get(ResVal);
13231323
}
13241324

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -std=c23 -emit-llvm -o - | FileCheck %s
2+
3+
struct Bits {
4+
int pad1: 30;
5+
bool b: 1;
6+
int pad2: 1;
7+
};
8+
9+
int main(void) {
10+
// CHECK-LABEL: define dso_local i32 @main() #0 {
11+
struct Bits x;
12+
x.b += __builtin_complex(-1.0f, 0.0f);
13+
// CHECK: %bf.load = load i32, ptr %x, align 4
14+
// CHECK-NEXT: %bf.lshr = lshr i32 %bf.load, 30
15+
// CHECK-NEXT: %bf.clear = and i32 %bf.lshr, 1
16+
// CHECK-NEXT: %bf.cast = trunc i32 %bf.clear to i1
17+
// CHECK-NEXT: %conv = uitofp i1 %bf.cast to float
18+
19+
// CHECK: %0 = zext i1 %tobool1 to i32
20+
// CHECK-NEXT: %bf.load2 = load i32, ptr %x, align 4
21+
// CHECK-NEXT: %bf.shl = shl i32 %0, 30
22+
// CHECK-NEXT: %bf.clear3 = and i32 %bf.load2, -1073741825
23+
// CHECK-NEXT: %bf.set = or i32 %bf.clear3, %bf.shl
24+
// CHECK-NEXT: store i32 %bf.set, ptr %x, align 4
25+
}

0 commit comments

Comments
 (0)