[llvm] 0ebbf34 - [ArgPromotion] Don't assume all entry block instrs are executed
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 28 07:08:53 PST 2022
Author: Nikita Popov
Date: 2022-01-28T16:08:42+01:00
New Revision: 0ebbf3435ff4c3c141549aaf0f791485c28f06f0
URL: https://github.com/llvm/llvm-project/commit/0ebbf3435ff4c3c141549aaf0f791485c28f06f0
DIFF: https://github.com/llvm/llvm-project/commit/0ebbf3435ff4c3c141549aaf0f791485c28f06f0.diff
LOG: [ArgPromotion] Don't assume all entry block instrs are executed
We should abort this walk if we hit any instruction that is not
guaranteed to transfer.
Added:
Modified:
llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/test/Transforms/ArgumentPromotion/load-after-non-willreturn-call.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index ea7baeb3813d..4d5fe9a6ed9a 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -46,6 +46,7 @@
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Argument.h"
@@ -610,12 +611,12 @@ static bool isSafeToPromoteArgument(Argument *Arg, Type *ByValTy, AAResults &AAR
return true;
};
- // First, iterate the entry block and mark loads of (geps of) arguments as
- // safe.
+ // First, iterate functions that are guaranteed to execution on function
+ // entry and mark loads of (geps of) arguments as safe.
BasicBlock &EntryBlock = Arg->getParent()->front();
// Declare this here so we can reuse it
IndicesVector Indices;
- for (Instruction &I : EntryBlock)
+ for (Instruction &I : EntryBlock) {
if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
Value *V = LI->getPointerOperand();
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
@@ -649,6 +650,10 @@ static bool isSafeToPromoteArgument(Argument *Arg, Type *ByValTy, AAResults &AAR
}
}
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I))
+ break;
+ }
+
// Now, iterate all uses of the argument to see if there are any uses that are
// not (GEP+)loads, or any (GEP+)loads that are not safe to promote.
SmallVector<LoadInst *, 16> Loads;
diff --git a/llvm/test/Transforms/ArgumentPromotion/load-after-non-willreturn-call.ll b/llvm/test/Transforms/ArgumentPromotion/load-after-non-willreturn-call.ll
index 04a0cbcb2774..6af4a358e0d5 100644
--- a/llvm/test/Transforms/ArgumentPromotion/load-after-non-willreturn-call.ll
+++ b/llvm/test/Transforms/ArgumentPromotion/load-after-non-willreturn-call.ll
@@ -3,11 +3,15 @@
declare void @may_not_return()
+; The argument cannot be promoted, as we do not know whether the load can be
+; speculatively executed.
+
define internal i32 @callee(i32* %p) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32 [[P_VAL:%.*]]) {
+; CHECK-SAME: (i32* [[P:%.*]]) {
; CHECK-NEXT: call void @may_not_return()
-; CHECK-NEXT: ret i32 [[P_VAL]]
+; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
+; CHECK-NEXT: ret i32 [[X]]
;
call void @may_not_return() readnone
%x = load i32, i32* %p
@@ -17,8 +21,7 @@ define internal i32 @callee(i32* %p) {
define void @caller(i32* %p) {
; CHECK-LABEL: define {{[^@]+}}@caller
; CHECK-SAME: (i32* [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[P]], align 4
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee(i32 [[P_VAL]])
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee(i32* [[P]])
; CHECK-NEXT: ret void
;
call i32 @callee(i32* %p)
More information about the llvm-commits
mailing list