[llvm] e1eacf2 - [InstCombine] Fold freeze into phi if one operand is not undef
Juneyoung Lee via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 27 01:08:08 PDT 2020
Author: Juneyoung Lee
Date: 2020-07-27T17:07:27+09:00
New Revision: e1eacf27c6f4ba82b8da34e62f62b44b81ffa316
URL: https://github.com/llvm/llvm-project/commit/e1eacf27c6f4ba82b8da34e62f62b44b81ffa316
DIFF: https://github.com/llvm/llvm-project/commit/e1eacf27c6f4ba82b8da34e62f62b44b81ffa316.diff
LOG: [InstCombine] Fold freeze into phi if one operand is not undef
This patch adds folding freeze into phi if it has only one operand to target.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D84601
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/freeze-phi.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index fdf0aaf9b176..711be57a0baf 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1048,7 +1048,9 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
BasicBlock *NonConstBB = nullptr;
for (unsigned i = 0; i != NumPHIValues; ++i) {
Value *InVal = PN->getIncomingValue(i);
- if (isa<Constant>(InVal) && !isa<ConstantExpr>(InVal))
+ // If I is a freeze instruction, count undef as a non-constant.
+ if (isa<Constant>(InVal) && !isa<ConstantExpr>(InVal) &&
+ (!isa<FreezeInst>(I) || isGuaranteedNotToBeUndefOrPoison(InVal)))
continue;
if (isa<PHINode>(InVal)) return nullptr; // Itself a phi.
@@ -1141,6 +1143,15 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
Builder);
NewPN->addIncoming(InV, PN->getIncomingBlock(i));
}
+ } else if (auto *FI = dyn_cast<FreezeInst>(&I)) {
+ for (unsigned i = 0; i != NumPHIValues; ++i) {
+ Value *InV;
+ if (NonConstBB == PN->getIncomingBlock(i))
+ InV = Builder.CreateFreeze(PN->getIncomingValue(i), "phi.fr");
+ else
+ InV = PN->getIncomingValue(i);
+ NewPN->addIncoming(InV, PN->getIncomingBlock(i));
+ }
} else {
CastInst *CI = cast<CastInst>(&I);
Type *RetTy = CI->getType();
@@ -3370,6 +3381,12 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
if (Value *V = SimplifyFreezeInst(Op0, SQ.getWithInstruction(&I)))
return replaceInstUsesWith(I, V);
+ // freeze (phi const, x) --> phi const, (freeze x)
+ if (auto *PN = dyn_cast<PHINode>(Op0)) {
+ if (Instruction *NV = foldOpIntoPhi(I, PN))
+ return NV;
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/freeze-phi.ll b/llvm/test/Transforms/InstCombine/freeze-phi.ll
index 430c2d2e8fe6..b8dde691a11c 100644
--- a/llvm/test/Transforms/InstCombine/freeze-phi.ll
+++ b/llvm/test/Transforms/InstCombine/freeze-phi.ll
@@ -51,11 +51,11 @@ define <2 x i32> @vec_undef(i1 %cond) {
; CHECK: A:
; CHECK-NEXT: br label [[C:%.*]]
; CHECK: B:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze <2 x i32> <i32 2, i32 undef>
; CHECK-NEXT: br label [[C]]
; CHECK: C:
-; CHECK-NEXT: [[Y:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[A]] ], [ <i32 2, i32 undef>, [[B]] ]
-; CHECK-NEXT: [[Y_FR:%.*]] = freeze <2 x i32> [[Y]]
-; CHECK-NEXT: ret <2 x i32> [[Y_FR]]
+; CHECK-NEXT: [[Y:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[A]] ], [ [[PHI_FR]], [[B]] ]
+; CHECK-NEXT: ret <2 x i32> [[Y]]
;
br i1 %cond, label %A, label %B
A:
@@ -74,11 +74,11 @@ define i32 @one(i1 %cond, i32 %x) {
; CHECK: A:
; CHECK-NEXT: br label [[C:%.*]]
; CHECK: B:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i32 [[X:%.*]]
; CHECK-NEXT: br label [[C]]
; CHECK: C:
-; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 0, [[A]] ], [ [[X:%.*]], [[B]] ]
-; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
-; CHECK-NEXT: ret i32 [[Y_FR]]
+; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 0, [[A]] ], [ [[PHI_FR]], [[B]] ]
+; CHECK-NEXT: ret i32 [[Y]]
;
br i1 %cond, label %A, label %B
A:
@@ -154,15 +154,15 @@ define i32 @one_undef(i8 %cond) {
; CHECK-NEXT: i8 1, label [[C:%.*]]
; CHECK-NEXT: ]
; CHECK: A:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i32 undef
; CHECK-NEXT: br label [[D:%.*]]
; CHECK: B:
; CHECK-NEXT: br label [[D]]
; CHECK: C:
; CHECK-NEXT: br label [[D]]
; CHECK: D:
-; CHECK-NEXT: [[Y:%.*]] = phi i32 [ undef, [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
-; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
-; CHECK-NEXT: ret i32 [[Y_FR]]
+; CHECK-NEXT: [[Y:%.*]] = phi i32 [ [[PHI_FR]], [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
+; CHECK-NEXT: ret i32 [[Y]]
;
switch i8 %cond, label %A [
i8 0, label %B
@@ -189,15 +189,15 @@ define i32 @one_constexpr(i8 %cond, i32 %x) {
; CHECK-NEXT: i8 1, label [[C:%.*]]
; CHECK-NEXT: ]
; CHECK: A:
+; CHECK-NEXT: [[PHI_FR:%.*]] = freeze i32 ptrtoint (i8* getelementptr inbounds (i8, i8* @glb, i64 2) to i32)
; CHECK-NEXT: br label [[D:%.*]]
; CHECK: B:
; CHECK-NEXT: br label [[D]]
; CHECK: C:
; CHECK-NEXT: br label [[D]]
; CHECK: D:
-; CHECK-NEXT: [[Y:%.*]] = phi i32 [ ptrtoint (i8* getelementptr inbounds (i8, i8* @glb, i64 2) to i32), [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
-; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
-; CHECK-NEXT: ret i32 [[Y_FR]]
+; CHECK-NEXT: [[Y:%.*]] = phi i32 [ [[PHI_FR]], [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
+; CHECK-NEXT: ret i32 [[Y]]
;
switch i8 %cond, label %A [
i8 0, label %B
More information about the llvm-commits
mailing list