From 45555c381926050bc45a3372b1af0e15650371b6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 7 Mar 2020 16:34:34 +0100 Subject: [PATCH] [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 --- llvm/lib/Analysis/InstructionSimplify.cpp | 3 +++ llvm/test/Analysis/ValueTracking/known-nonnull-at.ll | 2 +- llvm/test/Transforms/InstCombine/align-attr.ll | 2 +- llvm/test/Transforms/InstCombine/expensive-combines.ll | 2 +- llvm/test/Transforms/InstCombine/fortify-folding.ll | 4 ++-- llvm/test/Transforms/InstCombine/strcpy_chk-1.ll | 2 +- llvm/test/Transforms/InstCombine/strncpy_chk-1.ll | 2 +- llvm/test/Transforms/InstCombine/unused-nonnull.ll | 9 ++------- llvm/test/Transforms/InstSimplify/call.ll | 4 ++-- 9 files changed, 14 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 3b80e535f85b9..47f034017c489 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -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; diff --git a/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll b/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll index 9df8c28551329..06f4811837818 100644 --- a/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll +++ b/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll @@ -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) diff --git a/llvm/test/Transforms/InstCombine/align-attr.ll b/llvm/test/Transforms/InstCombine/align-attr.ll index 16782dba2effc..2b004311cc8ea 100644 --- a/llvm/test/Transforms/InstCombine/align-attr.ll +++ b/llvm/test/Transforms/InstCombine/align-attr.ll @@ -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: diff --git a/llvm/test/Transforms/InstCombine/expensive-combines.ll b/llvm/test/Transforms/InstCombine/expensive-combines.ll index 28acb773bfd50..96a45b05cfb59 100644 --- a/llvm/test/Transforms/InstCombine/expensive-combines.ll +++ b/llvm/test/Transforms/InstCombine/expensive-combines.ll @@ -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) diff --git a/llvm/test/Transforms/InstCombine/fortify-folding.ll b/llvm/test/Transforms/InstCombine/fortify-folding.ll index ee81557615a54..b2171a44f57ef 100644 --- a/llvm/test/Transforms/InstCombine/fortify-folding.ll +++ b/llvm/test/Transforms/InstCombine/fortify-folding.ll @@ -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 diff --git a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll index 02a4b5cbdeac2..67e393d1525be 100644 --- a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -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 diff --git a/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll index ed90303b28080..7601b16693599 100644 --- a/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll @@ -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 diff --git a/llvm/test/Transforms/InstCombine/unused-nonnull.ll b/llvm/test/Transforms/InstCombine/unused-nonnull.ll index 0a1520ea73c20..382d2634b86c5 100644 --- a/llvm/test/Transforms/InstCombine/unused-nonnull.ll +++ b/llvm/test/Transforms/InstCombine/unused-nonnull.ll @@ -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 diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index 108de9082a700..d744db6ddf766 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -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