[llvm] f7a977c - [InstCombine] Revisit user of newly one-use instructions
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 14 00:12:38 PDT 2023
Author: Nikita Popov
Date: 2023-06-14T09:12:30+02:00
New Revision: f7a977c7b3b4d8efebb92ed803585168df369831
URL: https://github.com/llvm/llvm-project/commit/f7a977c7b3b4d8efebb92ed803585168df369831
DIFF: https://github.com/llvm/llvm-project/commit/f7a977c7b3b4d8efebb92ed803585168df369831.diff
LOG: [InstCombine] Revisit user of newly one-use instructions
Many folds in InstCombine are limited to one-use instructions. For
that reason, if the use-count of an instruction drops to one, it
makes sense to revisit that one user. This is one of the most
common reasons why InstCombine fails to finish in a single iteration.
Doing this revisit actually slightly improves compile-time, because
we save an extra InstCombine iteration in enough cases to make a
visible difference.
This is conceptually NFC, but not NFC in practice, because differences
in worklist order can result in slightly different folding behavior.
The regressed tests in or-shifted-masks.ll now require a sequence of
instcombine,early-cse,instcombine to fold fully. D152876 would make
these fold in a single instcombine run again.
Differential Revision: https://reviews.llvm.org/D151807
Added:
Modified:
llvm/include/llvm/Transforms/Utils/InstructionWorklist.h
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/test/Other/print-debug-counter.ll
llvm/test/Transforms/InstCombine/or-shifted-masks.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/InstructionWorklist.h b/llvm/include/llvm/Transforms/Utils/InstructionWorklist.h
index a318c2cd28bbd..c8f20636965e8 100644
--- a/llvm/include/llvm/Transforms/Utils/InstructionWorklist.h
+++ b/llvm/include/llvm/Transforms/Utils/InstructionWorklist.h
@@ -108,6 +108,17 @@ class InstructionWorklist {
push(cast<Instruction>(U));
}
+ /// Should be called *after* decrementing the use-count on V.
+ void handleUseCountDecrement(Value *V) {
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ add(I);
+ // Many folds have one-use limitations. If there's only one use left,
+ // revisit that use.
+ if (I->hasOneUse())
+ add(cast<Instruction>(*I->user_begin()));
+ }
+ }
+
/// Check that the worklist is empty and nuke the backing store for the map.
void zap() {
assert(WorklistMap.empty() && "Worklist empty, but map not?");
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 1a9519f387977..88fbca2b13392 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -411,12 +411,11 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
// Make sure that we reprocess all operands now that we reduced their
// use counts.
- for (Use &Operand : I.operands())
- if (auto *Inst = dyn_cast<Instruction>(Operand))
- Worklist.add(Inst);
-
+ SmallVector<Value *> Ops(I.operands());
Worklist.remove(&I);
I.eraseFromParent();
+ for (Value *Op : Ops)
+ Worklist.handleUseCountDecrement(Op);
MadeIRChange = true;
return nullptr; // Don't do anything with FI
}
diff --git a/llvm/test/Other/print-debug-counter.ll b/llvm/test/Other/print-debug-counter.ll
index ac9882fe19c57..4b6e42570b315 100644
--- a/llvm/test/Other/print-debug-counter.ll
+++ b/llvm/test/Other/print-debug-counter.ll
@@ -8,7 +8,7 @@
; CHECK: early-cse
; CHECK-SAME: {4,1,1}
; CHECK: instcombine-visit
-; CHECK-SAME: {12,0,-1}
+; CHECK-SAME: {13,0,-1}
; CHECK: newgvn-vn
; CHECK-SAME: {9,1,2}
define i32 @f1(i32 %a, i32 %b) {
diff --git a/llvm/test/Transforms/InstCombine/or-shifted-masks.ll b/llvm/test/Transforms/InstCombine/or-shifted-masks.ll
index 5aa9112a5212a..e7a209a3f6c39 100644
--- a/llvm/test/Transforms/InstCombine/or-shifted-masks.ll
+++ b/llvm/test/Transforms/InstCombine/or-shifted-masks.ll
@@ -54,10 +54,13 @@ define i32 @or_and_shift_shift_and(i32 %x) {
define i32 @multiuse1(i32 %x) {
; CHECK-LABEL: @multiuse1(
-; CHECK-NEXT: [[I21:%.*]] = shl i32 [[X:%.*]], 6
+; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 1
+; CHECK-NEXT: [[I3:%.*]] = and i32 [[I]], 1
+; CHECK-NEXT: [[I1:%.*]] = lshr i32 [[X]], 1
+; CHECK-NEXT: [[I5:%.*]] = and i32 [[I1]], 2
+; CHECK-NEXT: [[I21:%.*]] = shl i32 [[X]], 6
; CHECK-NEXT: [[I6:%.*]] = and i32 [[I21]], 384
-; CHECK-NEXT: [[I32:%.*]] = lshr i32 [[X]], 1
-; CHECK-NEXT: [[I7:%.*]] = and i32 [[I32]], 3
+; CHECK-NEXT: [[I7:%.*]] = or i32 [[I3]], [[I5]]
; CHECK-NEXT: [[I8:%.*]] = or i32 [[I7]], [[I6]]
; CHECK-NEXT: ret i32 [[I8]]
;
@@ -75,10 +78,16 @@ define i32 @multiuse1(i32 %x) {
define i32 @multiuse2(i32 %x) {
; CHECK-LABEL: @multiuse2(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 8
+; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 1
+; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 12
+; CHECK-NEXT: [[I3:%.*]] = shl i32 [[X]], 1
+; CHECK-NEXT: [[I5:%.*]] = and i32 [[I3]], 48
+; CHECK-NEXT: [[I6:%.*]] = shl i32 [[X]], 1
+; CHECK-NEXT: [[I8:%.*]] = and i32 [[I6]], 192
+; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 8
; CHECK-NEXT: [[I10:%.*]] = and i32 [[TMP1]], 32256
-; CHECK-NEXT: [[TMP2:%.*]] = shl i32 [[X]], 1
-; CHECK-NEXT: [[I12:%.*]] = and i32 [[TMP2]], 252
+; CHECK-NEXT: [[I11:%.*]] = or i32 [[I8]], [[I5]]
+; CHECK-NEXT: [[I12:%.*]] = or i32 [[I2]], [[I11]]
; CHECK-NEXT: [[I13:%.*]] = or i32 [[I10]], [[I12]]
; CHECK-NEXT: ret i32 [[I13]]
;
@@ -101,10 +110,13 @@ define i32 @multiuse2(i32 %x) {
define i32 @multiuse3(i32 %x) {
; CHECK-LABEL: @multiuse3(
-; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 6
+; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 1
+; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 48
+; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 6
; CHECK-NEXT: [[I5:%.*]] = and i32 [[TMP1]], 8064
-; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[X]], 1
-; CHECK-NEXT: [[I8:%.*]] = and i32 [[TMP2]], 63
+; CHECK-NEXT: [[I6:%.*]] = lshr i32 [[X]], 1
+; CHECK-NEXT: [[I7:%.*]] = and i32 [[I6]], 15
+; CHECK-NEXT: [[I8:%.*]] = or i32 [[I2]], [[I7]]
; CHECK-NEXT: [[I9:%.*]] = or i32 [[I8]], [[I5]]
; CHECK-NEXT: ret i32 [[I9]]
;
More information about the llvm-commits
mailing list