[llvm] 47d10b2 - [instcombine] PRE freeze to only potentially posion/undef operand of phi
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 13 13:57:42 PDT 2021
Author: Philip Reames
Date: 2021-10-13T13:55:54-07:00
New Revision: 47d10b25f82d4df3a6953a12bbdea66ec1b5eaa4
URL: https://github.com/llvm/llvm-project/commit/47d10b25f82d4df3a6953a12bbdea66ec1b5eaa4
DIFF: https://github.com/llvm/llvm-project/commit/47d10b25f82d4df3a6953a12bbdea66ec1b5eaa4.diff
LOG: [instcombine] PRE freeze to only potentially posion/undef operand of phi
This extends the foldOpIntoPhi code used when visiting a freeze user of a phi to allow any non-undef/poison operand as opposed to only non-undef/poison constants. This lets us hoist a freeze in the increment of an IV into the preheader in many cases.
Differential Revision: https://reviews.llvm.org/D111744
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/freeze.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index bc4a088d6f2f..c5a6d5fb56a5 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1135,9 +1135,11 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
BasicBlock *NonConstBB = nullptr;
for (unsigned i = 0; i != NumPHIValues; ++i) {
Value *InVal = PN->getIncomingValue(i);
- // If I is a freeze instruction, count undef as a non-constant.
- if (match(InVal, m_ImmConstant()) &&
- (!isa<FreezeInst>(I) || isGuaranteedNotToBeUndefOrPoison(InVal)))
+ // For non-freeze, require constant operand
+ // For freeze, require non-undef, non-poison operand
+ if (!isa<FreezeInst>(I) && match(InVal, m_ImmConstant()))
+ continue;
+ if (isa<FreezeInst>(I) && isGuaranteedNotToBeUndefOrPoison(InVal))
continue;
if (isa<PHINode>(InVal)) return nullptr; // Itself a phi.
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index e05951dbff6c..bdee21a852b9 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -452,6 +452,139 @@ define float @propagate_drop_fmath_select(i1 %arg) {
ret float %v1.fr
}
+define void @fold_phi_noop(i32 noundef %init, i32 %n) {
+; CHECK-LABEL: @fold_phi_noop(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
+ %i.fr = freeze i32 %i
+ %i.next = add i32 %i.fr, 1
+ %cond = icmp eq i32 %i.next, %n
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
+define void @fold_phi_through(i32 %init, i32 %n) {
+; CHECK-LABEL: @fold_phi_through(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i32 [[INIT:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[PHI_FR]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
+ %i.fr = freeze i32 %i
+ %i.next = add i32 %i.fr, 1
+ %cond = icmp eq i32 %i.next, %n
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
+define void @fold_phi_neg_flags(i32 %init, i32 %n) {
+; CHECK-LABEL: @fold_phi_neg_flags(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]]
+; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I_FR]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
+ %i.fr = freeze i32 %i
+ %i.next = add nsw nuw i32 %i.fr, 1
+ %cond = icmp eq i32 %i.next, %n
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
+define void @fold_phi_non_add(i32 %init, i32 %n) {
+; CHECK-LABEL: @fold_phi_non_add(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i32 [[INIT:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[PHI_FR]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = shl i32 [[I]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
+ %i.fr = freeze i32 %i
+ %i.next = shl i32 %i.fr, 1
+ %cond = icmp eq i32 %i.next, %n
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
+define void @fold_phi_gep(i8* %init, i8* %end) {
+; CHECK-LABEL: @fold_phi_gep(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i8* [[INIT:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi i8* [ [[PHI_FR]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, i8* [[I]], i64 1
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8* [[I_NEXT]], [[END:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi i8* [ %init, %entry ], [ %i.next, %loop ]
+ %i.fr = freeze i8* %i
+ %i.next = getelementptr i8, i8* %i.fr, i64 1
+ %cond = icmp eq i8* %i.next, %end
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
More information about the llvm-commits
mailing list