Skip to content

Commit 3637dc6

Browse files
committed
[clang][CodeGen] Consistently return nullptr Values for void builtins and scalar initalization
A common post condition of the various visitor functions in CodeGen is that instructions, that do not return any values, simply return a nullptr Value as a sentinel. This has not been the case however for calls to some builtins returning void, as well as for an initializer expression of the form `void()`. This would then lead to ICEs in CodeGen on code relying on nullptr being returned for void values, which is eg. the case for conditional expressions [0]. This patch fixes that by returning nullptr Values for intrinsics known not to return any values as well as for a scalar initializer returning void. Fixes llvm#53127 [0] https://github.com/llvm/llvm-project/blob/266ec801fb23f9f5f1d61ca9466e0805fbdb78a7/clang/lib/CodeGen/CGExprScalar.cpp#L4849-L4892 Differential Revision: https://reviews.llvm.org/D136548
1 parent c3ead85 commit 3637dc6

File tree

3 files changed

+120
-16
lines changed

3 files changed

+120
-16
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,11 +2518,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
25182518
case Builtin::BI__builtin_va_start:
25192519
case Builtin::BI__va_start:
25202520
case Builtin::BI__builtin_va_end:
2521-
return RValue::get(
2522-
EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
2523-
? EmitScalarExpr(E->getArg(0))
2524-
: EmitVAListRef(E->getArg(0)).getPointer(),
2525-
BuiltinID != Builtin::BI__builtin_va_end));
2521+
EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
2522+
? EmitScalarExpr(E->getArg(0))
2523+
: EmitVAListRef(E->getArg(0)).getPointer(),
2524+
BuiltinID != Builtin::BI__builtin_va_end);
2525+
return RValue::get(nullptr);
25262526
case Builtin::BI__builtin_va_copy: {
25272527
Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
25282528
Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
@@ -2531,8 +2531,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
25312531

25322532
DstPtr = Builder.CreateBitCast(DstPtr, Type);
25332533
SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
2534-
return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
2535-
{DstPtr, SrcPtr}));
2534+
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), {DstPtr, SrcPtr});
2535+
return RValue::get(nullptr);
25362536
}
25372537
case Builtin::BI__builtin_abs:
25382538
case Builtin::BI__builtin_labs:
@@ -2804,7 +2804,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
28042804

28052805
Value *ArgValue = EmitScalarExpr(E->getArg(0));
28062806
Function *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
2807-
return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
2807+
Builder.CreateCall(FnAssume, ArgValue);
2808+
return RValue::get(nullptr);
28082809
}
28092810
case Builtin::BI__arithmetic_fence: {
28102811
// Create the builtin call if FastMath is selected, and the target
@@ -2925,7 +2926,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
29252926
llvm::ConstantInt::get(Int32Ty, 3);
29262927
Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
29272928
Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
2928-
return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
2929+
Builder.CreateCall(F, {Address, RW, Locality, Data});
2930+
return RValue::get(nullptr);
29292931
}
29302932
case Builtin::BI__builtin_readcyclecounter: {
29312933
Function *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
@@ -2938,9 +2940,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
29382940
return RValue::get(Builder.CreateCall(F, {Begin, End}));
29392941
}
29402942
case Builtin::BI__builtin_trap:
2941-
return RValue::get(EmitTrapCall(Intrinsic::trap));
2943+
EmitTrapCall(Intrinsic::trap);
2944+
return RValue::get(nullptr);
29422945
case Builtin::BI__debugbreak:
2943-
return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
2946+
EmitTrapCall(Intrinsic::debugtrap);
2947+
return RValue::get(nullptr);
29442948
case Builtin::BI__builtin_unreachable: {
29452949
EmitUnreachable(E->getExprLoc());
29462950

@@ -3721,7 +3725,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
37213725
}
37223726
case Builtin::BI__builtin_unwind_init: {
37233727
Function *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
3724-
return RValue::get(Builder.CreateCall(F));
3728+
Builder.CreateCall(F);
3729+
return RValue::get(nullptr);
37253730
}
37263731
case Builtin::BI__builtin_extend_pointer: {
37273732
// Extends a pointer to the size of an _Unwind_Word, which is
@@ -4482,8 +4487,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
44824487
return EmitBuiltinNewDeleteCall(
44834488
E->getCallee()->getType()->castAs<FunctionProtoType>(), E, false);
44844489
case Builtin::BI__builtin_operator_delete:
4485-
return EmitBuiltinNewDeleteCall(
4490+
EmitBuiltinNewDeleteCall(
44864491
E->getCallee()->getType()->castAs<FunctionProtoType>(), E, true);
4492+
return RValue::get(nullptr);
44874493

44884494
case Builtin::BI__builtin_is_aligned:
44894495
return EmitBuiltinIsAligned(E);
@@ -4653,15 +4659,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
46534659
case Builtin::BI__builtin_coro_promise:
46544660
return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise);
46554661
case Builtin::BI__builtin_coro_resume:
4656-
return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
4662+
EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
4663+
return RValue::get(nullptr);
46574664
case Builtin::BI__builtin_coro_frame:
46584665
return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame);
46594666
case Builtin::BI__builtin_coro_noop:
46604667
return EmitCoroutineIntrinsic(E, Intrinsic::coro_noop);
46614668
case Builtin::BI__builtin_coro_free:
46624669
return EmitCoroutineIntrinsic(E, Intrinsic::coro_free);
46634670
case Builtin::BI__builtin_coro_destroy:
4664-
return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
4671+
EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
4672+
return RValue::get(nullptr);
46654673
case Builtin::BI__builtin_coro_done:
46664674
return EmitCoroutineIntrinsic(E, Intrinsic::coro_done);
46674675
case Builtin::BI__builtin_coro_alloc:
@@ -5094,7 +5102,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
50945102
Value *Val = EmitScalarExpr(E->getArg(0));
50955103
Address Address = EmitPointerWithAlignment(E->getArg(1));
50965104
Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
5097-
return RValue::get(Builder.CreateStore(HalfVal, Address));
5105+
Builder.CreateStore(HalfVal, Address);
5106+
return RValue::get(nullptr);
50985107
}
50995108
case Builtin::BI__builtin_load_half: {
51005109
Address Address = EmitPointerWithAlignment(E->getArg(0));
@@ -5359,6 +5368,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
53595368
V = Builder.CreateBitCast(V, RetTy);
53605369
}
53615370

5371+
if (RetTy->isVoidTy())
5372+
return RValue::get(nullptr);
5373+
53625374
return RValue::get(V);
53635375
}
53645376

@@ -5376,6 +5388,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
53765388
if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E, ReturnValue)) {
53775389
switch (EvalKind) {
53785390
case TEK_Scalar:
5391+
if (V->getType()->isVoidTy())
5392+
return RValue::get(nullptr);
53795393
return RValue::get(V);
53805394
case TEK_Aggregate:
53815395
return RValue::getAggregate(ReturnValue.getValue(),

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ class ScalarExprEmitter
467467
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
468468
}
469469
Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
470+
if (E->getType()->isVoidType())
471+
return nullptr;
472+
470473
return EmitNullValue(E->getType());
471474
}
472475
Value *VisitGNUNullExpr(const GNUNullExpr *E) {

clang/test/CodeGen/pr53127.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
3+
4+
bool e();
5+
6+
void operator delete(void*);
7+
8+
// CHECK-LABEL: @_Z1fPiz(
9+
// CHECK-NEXT: entry:
10+
// CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8
11+
// CHECK-NEXT: [[L:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
12+
// CHECK-NEXT: [[L2:%.*]] = alloca [1 x %struct.__va_list_tag], align 16
13+
// CHECK-NEXT: store ptr [[P:%.*]], ptr [[P_ADDR]], align 8
14+
// CHECK-NEXT: [[CALL:%.*]] = call noundef zeroext i1 @_Z1ev()
15+
// CHECK-NEXT: br i1 [[CALL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
16+
// CHECK: cond.true:
17+
// CHECK-NEXT: call void @llvm.trap()
18+
// CHECK-NEXT: br label [[COND_END:%.*]]
19+
// CHECK: cond.false:
20+
// CHECK-NEXT: br label [[COND_END]]
21+
// CHECK: cond.end:
22+
// CHECK-NEXT: [[CALL1:%.*]] = call noundef zeroext i1 @_Z1ev()
23+
// CHECK-NEXT: br i1 [[CALL1]], label [[COND_TRUE2:%.*]], label [[COND_FALSE3:%.*]]
24+
// CHECK: cond.true2:
25+
// CHECK-NEXT: call void @llvm.debugtrap()
26+
// CHECK-NEXT: br label [[COND_END4:%.*]]
27+
// CHECK: cond.false3:
28+
// CHECK-NEXT: br label [[COND_END4]]
29+
// CHECK: cond.end4:
30+
// CHECK-NEXT: [[CALL5:%.*]] = call noundef zeroext i1 @_Z1ev()
31+
// CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[CALL5]] to i64
32+
// CHECK-NEXT: call void @llvm.assume(i1 true)
33+
// CHECK-NEXT: [[CALL6:%.*]] = call noundef zeroext i1 @_Z1ev()
34+
// CHECK-NEXT: br i1 [[CALL6]], label [[COND_TRUE7:%.*]], label [[COND_FALSE8:%.*]]
35+
// CHECK: cond.true7:
36+
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L]], i64 0, i64 0
37+
// CHECK-NEXT: call void @llvm.va_start(ptr [[ARRAYDECAY]])
38+
// CHECK-NEXT: br label [[COND_END9:%.*]]
39+
// CHECK: cond.false8:
40+
// CHECK-NEXT: br label [[COND_END9]]
41+
// CHECK: cond.end9:
42+
// CHECK-NEXT: [[CALL10:%.*]] = call noundef zeroext i1 @_Z1ev()
43+
// CHECK-NEXT: br i1 [[CALL10]], label [[COND_TRUE11:%.*]], label [[COND_FALSE14:%.*]]
44+
// CHECK: cond.true11:
45+
// CHECK-NEXT: [[ARRAYDECAY12:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L]], i64 0, i64 0
46+
// CHECK-NEXT: [[ARRAYDECAY13:%.*]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr [[L2]], i64 0, i64 0
47+
// CHECK-NEXT: call void @llvm.va_copy(ptr [[ARRAYDECAY12]], ptr [[ARRAYDECAY13]])
48+
// CHECK-NEXT: br label [[COND_END15:%.*]]
49+
// CHECK: cond.false14:
50+
// CHECK-NEXT: br label [[COND_END15]]
51+
// CHECK: cond.end15:
52+
// CHECK-NEXT: [[CALL16:%.*]] = call noundef zeroext i1 @_Z1ev()
53+
// CHECK-NEXT: br i1 [[CALL16]], label [[COND_TRUE17:%.*]], label [[COND_FALSE18:%.*]]
54+
// CHECK: cond.true17:
55+
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P_ADDR]], align 8
56+
// CHECK-NEXT: call void @llvm.prefetch.p0(ptr [[TMP1]], i32 0, i32 3, i32 1)
57+
// CHECK-NEXT: br label [[COND_END19:%.*]]
58+
// CHECK: cond.false18:
59+
// CHECK-NEXT: br label [[COND_END19]]
60+
// CHECK: cond.end19:
61+
// CHECK-NEXT: [[CALL20:%.*]] = call noundef zeroext i1 @_Z1ev()
62+
// CHECK-NEXT: br i1 [[CALL20]], label [[COND_TRUE21:%.*]], label [[COND_FALSE22:%.*]]
63+
// CHECK: cond.true21:
64+
// CHECK-NEXT: call void @llvm.eh.unwind.init()
65+
// CHECK-NEXT: br label [[COND_END23:%.*]]
66+
// CHECK: cond.false22:
67+
// CHECK-NEXT: br label [[COND_END23]]
68+
// CHECK: cond.end23:
69+
// CHECK-NEXT: [[CALL24:%.*]] = call noundef zeroext i1 @_Z1ev()
70+
// CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[CALL24]] to i64
71+
// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8
72+
// CHECK-NEXT: call void @_ZdlPv(ptr noundef [[TMP3]]) #[[ATTR8:[0-9]+]]
73+
// CHECK-NEXT: ret void
74+
//
75+
void f(int* p, ...)
76+
{
77+
e() ? __builtin_trap() : void();
78+
e() ? __builtin_debugtrap() : void();
79+
e() ? __builtin_assume(true) : void();
80+
__builtin_va_list l;
81+
e() ? __builtin_va_start(l, p) : void();
82+
__builtin_va_list l2;
83+
e() ? __builtin_va_copy(l, l2) : void();
84+
e() ? __builtin_prefetch(p) : void();
85+
e() ? __builtin_unwind_init() : void();
86+
e() ? __builtin_operator_delete(p) : void();
87+
}

0 commit comments

Comments
 (0)