[llvm] 1848525 - [CodeMetrics] Don't require speculatability for ephemeral values
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 21 11:30:18 PDT 2021
Author: Nikita Popov
Date: 2021-10-21T20:30:01+02:00
New Revision: 184852584231c60156fb4ec7eddb228b13837c39
URL: https://github.com/llvm/llvm-project/commit/184852584231c60156fb4ec7eddb228b13837c39
DIFF: https://github.com/llvm/llvm-project/commit/184852584231c60156fb4ec7eddb228b13837c39.diff
LOG: [CodeMetrics] Don't require speculatability for ephemeral values
As discussed in D112016, our current requirement of speculatability
for ephemeral is overly strict: What we really care about is that
the instruction will be DCEd once the assume is dropped. For that
it is sufficient that the instruction is side-effect free and not
a terminator.
In particular, this allows non-dereferenceable loads to be ephemeral
values.
Differential Revision: https://reviews.llvm.org/D112179
Added:
Modified:
llvm/lib/Analysis/CodeMetrics.cpp
llvm/lib/Analysis/ValueTracking.cpp
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/Inline/ephemeral.ll
llvm/test/Transforms/SimplifyCFG/unprofitable-pr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/CodeMetrics.cpp b/llvm/lib/Analysis/CodeMetrics.cpp
index 8c8e2ee6627fd..27c52506352ff 100644
--- a/llvm/lib/Analysis/CodeMetrics.cpp
+++ b/llvm/lib/Analysis/CodeMetrics.cpp
@@ -34,8 +34,9 @@ appendSpeculatableOperands(const Value *V,
for (const Value *Operand : U->operands())
if (Visited.insert(Operand).second)
- if (isSafeToSpeculativelyExecute(Operand))
- Worklist.push_back(Operand);
+ if (const auto *I = dyn_cast<Instruction>(Operand))
+ if (!I->mayHaveSideEffects() && !I->isTerminator())
+ Worklist.push_back(I);
}
static void completeEphemeralValues(SmallPtrSetImpl<const Value *> &Visited,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index bf1989c58c207..8991582a7a25b 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -494,7 +494,9 @@ static bool isEphemeralValueOf(const Instruction *I, const Value *E) {
if (V == E)
return true;
- if (V == I || isSafeToSpeculativelyExecute(V)) {
+ if (V == I || (isa<Instruction>(V) &&
+ !cast<Instruction>(V)->mayHaveSideEffects() &&
+ !cast<Instruction>(V)->isTerminator())) {
EphValues.insert(V);
if (const User *U = dyn_cast<User>(V))
append_range(WorkSet, U->operands());
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 920df4e9d7421..84bf364d6d24a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2577,11 +2577,11 @@ static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB) {
int Size = 0;
SmallPtrSet<const Value *, 32> EphValues;
- auto IsEphemeral = [&](const Value *V) {
- if (isa<AssumeInst>(V))
+ auto IsEphemeral = [&](const Instruction *I) {
+ if (isa<AssumeInst>(I))
return true;
- return isSafeToSpeculativelyExecute(V) &&
- all_of(V->users(),
+ return !I->mayHaveSideEffects() && !I->isTerminator() &&
+ all_of(I->users(),
[&](const User *U) { return EphValues.count(U); });
};
diff --git a/llvm/test/Transforms/Inline/ephemeral.ll b/llvm/test/Transforms/Inline/ephemeral.ll
index f47c349cb517b..b25d1e08148bd 100644
--- a/llvm/test/Transforms/Inline/ephemeral.ll
+++ b/llvm/test/Transforms/Inline/ephemeral.ll
@@ -26,10 +26,10 @@ define i32 @inner(i8* %y) {
ret i32 %a1
}
-; TODO: The load should be considered ephemeral here, even though it is not
-; speculatable.
+; Only the ret should be included in the instruction count, the load and icmp
+; are both ephemeral.
; CHECK: Analyzing call of inner2...
-; CHECK: NumInstructions: 2
+; CHECK: NumInstructions: 1
define void @inner2(i8* %y) {
%v = load i8, i8* %y
%c = icmp eq i8 %v, 42
diff --git a/llvm/test/Transforms/SimplifyCFG/unprofitable-pr.ll b/llvm/test/Transforms/SimplifyCFG/unprofitable-pr.ll
index af918657b5701..4f6107b122744 100644
--- a/llvm/test/Transforms/SimplifyCFG/unprofitable-pr.ll
+++ b/llvm/test/Transforms/SimplifyCFG/unprofitable-pr.ll
@@ -233,32 +233,37 @@ false2: ; preds = %true1
ret void
}
-; TODO: The load should be considered ephemeral here, even though it is not
-; speculatable.
+; The load, icmp and assume should not count towards the limit, they are
+; ephemeral.
define void @test_non_speculatable(i1 %c, i64* align 1 %ptr, i8* %ptr2) local_unnamed_addr #0 {
; CHECK-LABEL: @test_non_speculatable(
-; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE1:%.*]], label [[FALSE1:%.*]]
-; CHECK: true1:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE2_CRITEDGE:%.*]], label [[FALSE1:%.*]]
+; CHECK: false1:
+; CHECK-NEXT: store volatile i64 1, i64* [[PTR:%.*]], align 4
; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[PTR2:%.*]], align 1
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[C2]])
-; CHECK-NEXT: store volatile i64 0, i64* [[PTR:%.*]], align 8
+; CHECK-NEXT: store volatile i64 0, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
-; CHECK-NEXT: br i1 [[C]], label [[TRUE2:%.*]], label [[FALSE2:%.*]]
-; CHECK: false1:
-; CHECK-NEXT: store volatile i64 1, i64* [[PTR]], align 4
-; CHECK-NEXT: br label [[TRUE1]]
+; CHECK-NEXT: store volatile i64 3, i64* [[PTR]], align 8
+; CHECK-NEXT: br label [[COMMON_RET:%.*]]
; CHECK: common.ret:
; CHECK-NEXT: ret void
-; CHECK: true2:
+; CHECK: true2.critedge:
+; CHECK-NEXT: [[V_C:%.*]] = load i8, i8* [[PTR2]], align 1
+; CHECK-NEXT: [[C2_C:%.*]] = icmp eq i8 [[V_C]], 42
+; CHECK-NEXT: call void @llvm.assume(i1 [[C2_C]])
+; CHECK-NEXT: store volatile i64 0, i64* [[PTR]], align 8
+; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
+; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
+; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
+; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
+; CHECK-NEXT: store volatile i64 -1, i64* [[PTR]], align 8
; CHECK-NEXT: store volatile i64 2, i64* [[PTR]], align 8
-; CHECK-NEXT: br label [[COMMON_RET:%.*]]
-; CHECK: false2:
-; CHECK-NEXT: store volatile i64 3, i64* [[PTR]], align 8
; CHECK-NEXT: br label [[COMMON_RET]]
;
br i1 %c, label %true1, label %false1
More information about the llvm-commits
mailing list