mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[InstSimplify] Simplify calls with "returned" attribute
If a call argument has the "returned" attribute, we can simplify the call to the value of that argument. The "-inst-simplify" pass already handled this for the constant integer argument case via known bits, which is invoked in SimplifyInstruction. However, non-constant (or non-int) arguments are not handled at all right now. This addresses one of the regressions from D75801. Differential Revision: https://reviews.llvm.org/D75815
This commit is contained in:
parent
02e924df49
commit
70e47f8656
@ -5348,6 +5348,9 @@ Value *llvm::SimplifyCall(CallBase *Call, const SimplifyQuery &Q) {
|
||||
if (Value *Ret = simplifyIntrinsic(Call, Q))
|
||||
return Ret;
|
||||
|
||||
if (Value *ReturnedArg = Call->getReturnedArgOperand())
|
||||
return ReturnedArg;
|
||||
|
||||
if (!canConstantFoldCallTo(Call, F))
|
||||
return nullptr;
|
||||
|
||||
|
@ -117,7 +117,7 @@ define i1 @nonnullReturnTest(i8* nonnull %x) {
|
||||
define i1 @unknownReturnTest(i8* %x) {
|
||||
; CHECK-LABEL: @unknownReturnTest(
|
||||
; CHECK-NEXT: [[X2:%.*]] = call i8* @returningPtr(i8* [[X:%.*]])
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[X2]], null
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[X]], null
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
;
|
||||
%x2 = call i8* @returningPtr(i8* %x)
|
||||
|
@ -20,7 +20,7 @@ define i32 @foo2(i32* align 32 %a) #0 {
|
||||
; CHECK-LABEL: @foo2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32* @func1(i32* [[A:%.*]])
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[V]], align 32
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32
|
||||
; CHECK-NEXT: ret i32 [[TMP0]]
|
||||
;
|
||||
entry:
|
||||
|
@ -16,7 +16,7 @@ define void @test() {
|
||||
;
|
||||
; EXPENSIVE-OFF-LABEL: @test(
|
||||
; EXPENSIVE-OFF-NEXT: [[CALL:%.*]] = call i32 @passthru(i32 0)
|
||||
; EXPENSIVE-OFF-NEXT: call void @sink(i32 [[CALL]])
|
||||
; EXPENSIVE-OFF-NEXT: call void @sink(i32 0)
|
||||
; EXPENSIVE-OFF-NEXT: ret void
|
||||
;
|
||||
%call = call i32 @passthru(i32 0)
|
||||
|
@ -82,7 +82,7 @@ define i32 @test_not_sprintf() {
|
||||
define i8* @test_strcat() {
|
||||
; CHECK-LABEL: @test_strcat(
|
||||
; CHECK-NEXT: [[STRCAT:%.*]] = call i8* @strcat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
|
||||
; CHECK-NEXT: ret i8* [[STRCAT]]
|
||||
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0)
|
||||
;
|
||||
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
|
||||
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
|
||||
@ -126,7 +126,7 @@ define i64 @test_not_strlcat() {
|
||||
define i8* @test_strncat() {
|
||||
; CHECK-LABEL: @test_strncat(
|
||||
; CHECK-NEXT: [[STRNCAT:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22)
|
||||
; CHECK-NEXT: ret i8* [[STRNCAT]]
|
||||
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0)
|
||||
;
|
||||
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
|
||||
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
|
||||
|
@ -53,7 +53,7 @@ define i8* @test_simplify3() {
|
||||
define i8* @test_simplify4() {
|
||||
; CHECK-LABEL: @test_simplify4(
|
||||
; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0))
|
||||
; CHECK-NEXT: ret i8* [[STRCPY]]
|
||||
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0)
|
||||
;
|
||||
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
|
||||
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
|
||||
|
@ -39,7 +39,7 @@ define i8* @test_simplify2() {
|
||||
define i8* @test_simplify3() {
|
||||
; CHECK-LABEL: @test_simplify3(
|
||||
; CHECK-NEXT: [[STRNCPY:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 12)
|
||||
; CHECK-NEXT: ret i8* [[STRNCPY]]
|
||||
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0)
|
||||
;
|
||||
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
|
||||
%src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
|
||||
|
@ -12,13 +12,8 @@ define i32 @main(i32 %argc, i8** %argv) #0 {
|
||||
; CHECK-SAME: (i32 [[ARGC:%.*]], i8** nocapture readnone [[ARGV:%.*]]) local_unnamed_addr #0
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ARGC]], 2
|
||||
; CHECK-NEXT: br i1 [[TMP0]], label [[DONE:%.*]], label [[DO_WORK:%.*]]
|
||||
; CHECK: do_work:
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @compute(i8* undef, i32 [[ARGC]])
|
||||
; CHECK-NEXT: br label [[DONE]]
|
||||
; CHECK: done:
|
||||
; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1]], [[DO_WORK]] ]
|
||||
; CHECK-NEXT: ret i32 [[RETVAL]]
|
||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 0, i32 [[ARGC]]
|
||||
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
|
||||
;
|
||||
entry:
|
||||
%0 = getelementptr inbounds i8*, i8** %argv, i32 0
|
||||
|
@ -993,7 +993,7 @@ define i32 @returned_const_int_arg() {
|
||||
define i8* @returned_const_ptr_arg() {
|
||||
; CHECK-LABEL: @returned_const_ptr_arg(
|
||||
; CHECK-NEXT: [[X:%.*]] = call i8* @passthru_p8(i8* null)
|
||||
; CHECK-NEXT: ret i8* [[X]]
|
||||
; CHECK-NEXT: ret i8* null
|
||||
;
|
||||
%x = call i8* @passthru_p8(i8* null)
|
||||
ret i8* %x
|
||||
@ -1002,7 +1002,7 @@ define i8* @returned_const_ptr_arg() {
|
||||
define i32 @returned_var_arg(i32 %arg) {
|
||||
; CHECK-LABEL: @returned_var_arg(
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @passthru_i32(i32 [[ARG:%.*]])
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
; CHECK-NEXT: ret i32 [[ARG]]
|
||||
;
|
||||
%x = call i32 @passthru_i32(i32 %arg)
|
||||
ret i32 %x
|
||||
|
Loading…
Reference in New Issue
Block a user