Skip to content

Commit

Permalink
[InstCombine] Remove transformation on call instruction where return …
Browse files Browse the repository at this point in the history
…value need void to non-void conversion (llvm#98536)

Skip simplification on call instruction where a non-void return value is
expected but the callee returns void, which is undefined behavior and
could lead to non-determinism or crashes.
  • Loading branch information
yozhu authored and banach-space committed Aug 7, 2024
1 parent 678159f commit 3ba7ebd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
23 changes: 9 additions & 14 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4145,9 +4145,7 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
if (Callee->isDeclaration())
return false; // Cannot transform this return value.

if (!Caller->use_empty() &&
// void -> non-void is handled specially
!NewRetTy->isVoidTy())
if (!Caller->use_empty())
return false; // Cannot transform this return value.
}

Expand Down Expand Up @@ -4338,17 +4336,14 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
Instruction *NC = NewCall;
Value *NV = NC;
if (OldRetTy != NV->getType() && !Caller->use_empty()) {
if (!NV->getType()->isVoidTy()) {
NV = NC = CastInst::CreateBitOrPointerCast(NC, OldRetTy);
NC->setDebugLoc(Caller->getDebugLoc());

auto OptInsertPt = NewCall->getInsertionPointAfterDef();
assert(OptInsertPt && "No place to insert cast");
InsertNewInstBefore(NC, *OptInsertPt);
Worklist.pushUsersToWorkList(*Caller);
} else {
NV = PoisonValue::get(Caller->getType());
}
assert(!NV->getType()->isVoidTy());
NV = NC = CastInst::CreateBitOrPointerCast(NC, OldRetTy);
NC->setDebugLoc(Caller->getDebugLoc());

auto OptInsertPt = NewCall->getInsertionPointAfterDef();
assert(OptInsertPt && "No place to insert cast");
InsertNewInstBefore(NC, *OptInsertPt);
Worklist.pushUsersToWorkList(*Caller);
}

if (!Caller->use_empty())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt --passes=instcombine -S < %s | FileCheck %s

define void @foo() {
; CHECK-LABEL: define void @foo() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: ret void
;
entry:
ret void
}

define i32 @bar() {
; CHECK-LABEL: define i32 @bar() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo()
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
%1 = tail call i32 @foo()
ret i32 %1
}

define void @goo() {
; CHECK-LABEL: define void @goo() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: ret void
;
entry:
%res = call i32 @foo()
ret void
}

0 comments on commit 3ba7ebd

Please sign in to comment.