mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 22:58:50 +00:00
Return "[InstCombine] Simplify compare of Phi with constant inputs against a constant"
I originally reverted the patch because it was causing performance issues, but now I think it's just enabling simplify-cfg to do something that I don't want instead :) Sorry for the noise. This reverts commit 3e39760f8eaad4770efa05824768e67237915cf5.
This commit is contained in:
parent
1b3768875a
commit
009de096e9
@ -1452,6 +1452,27 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) {
|
||||
if (Instruction *Res = processUGT_ADDCST_ADD(Cmp, A, B, CI2, CI, *this))
|
||||
return Res;
|
||||
|
||||
// icmp(phi(C1, C2, ...), C) -> phi(icmp(C1, C), icmp(C2, C), ...).
|
||||
Constant *C = dyn_cast<Constant>(Op1);
|
||||
if (!C)
|
||||
return nullptr;
|
||||
|
||||
if (auto *Phi = dyn_cast<PHINode>(Op0))
|
||||
if (all_of(Phi->operands(), [](Value *V) { return isa<Constant>(V); })) {
|
||||
Type *Ty = Cmp.getType();
|
||||
Builder.SetInsertPoint(Phi);
|
||||
PHINode *NewPhi =
|
||||
Builder.CreatePHI(Ty, Phi->getNumOperands());
|
||||
for (BasicBlock *Predecessor : predecessors(Phi->getParent())) {
|
||||
auto *Input =
|
||||
cast<Constant>(Phi->getIncomingValueForBlock(Predecessor));
|
||||
auto *BoolInput = ConstantExpr::getCompare(Pred, Input, C);
|
||||
NewPhi->addIncoming(BoolInput, Predecessor);
|
||||
}
|
||||
NewPhi->takeName(&Cmp);
|
||||
return replaceInstUsesWith(Cmp, NewPhi);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
||||
|
||||
; TODO: Replace with boolean Phi.
|
||||
|
||||
define i1 @test_eq(i1 %cond) {
|
||||
; CHECK-LABEL: @test_eq(
|
||||
; CHECK-NEXT: entry:
|
||||
@ -13,10 +11,9 @@ define i1 @test_eq(i1 %cond) {
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 123, [[IF_TRUE]] ], [ 456, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ true, [[IF_FALSE]] ], [ false, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = icmp eq i32 [[PHI]], 456
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
@ -46,10 +43,9 @@ define i1 @test_slt(i1 %cond) {
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 123, [[IF_TRUE]] ], [ 456, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ false, [[IF_FALSE]] ], [ true, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = icmp ult i32 [[PHI]], 456
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
@ -110,10 +106,9 @@ define i1 @test_ne(i1 %cond) {
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 123, [[IF_TRUE]] ], [ 456, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ false, [[IF_FALSE]] ], [ true, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = icmp ne i32 [[PHI]], 456
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
@ -133,3 +128,164 @@ exit:
|
||||
%compare = icmp ne i32 %phi, 456
|
||||
ret i1 %compare
|
||||
}
|
||||
|
||||
define i1 @test_ne_undef(i1 %cond) {
|
||||
; CHECK-LABEL: @test_ne_undef(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
||||
; CHECK: if.true:
|
||||
; CHECK-NEXT: br label [[MERGE:%.*]]
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
br label %merge
|
||||
|
||||
if.false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%phi = phi i32 [undef, %if.true], [456, %if.false]
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
%compare = icmp ne i32 %phi, 456
|
||||
ret i1 %compare
|
||||
}
|
||||
|
||||
define <2 x i1> @test_ne_int_vector(i1 %cond) {
|
||||
; CHECK-LABEL: @test_ne_int_vector(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
||||
; CHECK: if.true:
|
||||
; CHECK-NEXT: br label [[MERGE:%.*]]
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi <2 x i1> [ <i1 true, i1 false>, [[IF_FALSE]] ], [ <i1 false, i1 true>, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret <2 x i1> [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
br label %merge
|
||||
|
||||
if.false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%phi = phi <2 x i32> [<i32 123, i32 123>, %if.true], [<i32 456, i32 456>, %if.false]
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
%compare = icmp ne <2 x i32> %phi, <i32 123, i32 456>
|
||||
ret <2 x i1> %compare
|
||||
}
|
||||
|
||||
; TODO: We can also constant-fold this comparison for floats.
|
||||
define i1 @test_ne_float(i1 %cond) {
|
||||
; CHECK-LABEL: @test_ne_float(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
||||
; CHECK: if.true:
|
||||
; CHECK-NEXT: br label [[MERGE:%.*]]
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[PHI:%.*]] = phi float [ 1.000000e+00, [[IF_TRUE]] ], [ 1.250000e+00, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = fcmp one float [[PHI]], 1.250000e+00
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
br label %merge
|
||||
|
||||
if.false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%phi = phi float [1.0, %if.true], [1.25, %if.false]
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
%compare = fcmp one float %phi, 1.25
|
||||
ret i1 %compare
|
||||
}
|
||||
|
||||
define i1 @test_ne_float_undef(i1 %cond) {
|
||||
; CHECK-LABEL: @test_ne_float_undef(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
||||
; CHECK: if.true:
|
||||
; CHECK-NEXT: br label [[MERGE:%.*]]
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
br label %merge
|
||||
|
||||
if.false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%phi = phi float [1.0, %if.true], [undef, %if.false]
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
%compare = fcmp one float %phi, 1.25
|
||||
ret i1 %compare
|
||||
}
|
||||
|
||||
define <2 x i1> @test_ne_float_vector(i1 %cond) {
|
||||
; CHECK-LABEL: @test_ne_float_vector(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
||||
; CHECK: if.true:
|
||||
; CHECK-NEXT: br label [[MERGE:%.*]]
|
||||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[PHI:%.*]] = phi <2 x float> [ <float 1.232500e+02, float 1.232500e+02>, [[IF_TRUE]] ], [ <float 4.562500e+02, float 4.562500e+02>, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = fcmp one <2 x float> [[PHI]], <float 1.232500e+02, float 4.562500e+02>
|
||||
; CHECK-NEXT: ret <2 x i1> [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
||||
if.true:
|
||||
br label %merge
|
||||
|
||||
if.false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%phi = phi <2 x float> [<float 123.25, float 123.25>, %if.true], [<float 456.25, float 456.25>, %if.false]
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
%compare = fcmp one <2 x float> %phi, <float 123.25, float 456.25>
|
||||
ret <2 x i1> %compare
|
||||
}
|
||||
|
@ -182,8 +182,7 @@ bb10:
|
||||
ret i1 %cmp
|
||||
}
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK: %[[phi:.*]] = phi i64* [ @pr30402, %entry ], [ getelementptr inbounds (i64, i64* @pr30402, i32 1), %bb7 ]
|
||||
; CHECK: %[[cmp:.*]] = icmp eq i64* %[[phi]], getelementptr inbounds (i64, i64* @pr30402, i32 1)
|
||||
; CHECK: %[[cmp:.*]] = phi i1 [ true, %bb7 ], [ false, %entry ]
|
||||
; CHECK: ret i1 %[[cmp]]
|
||||
|
||||
|
||||
|
@ -40,8 +40,8 @@ block2:
|
||||
ret i32 %conv2
|
||||
|
||||
; CHECK-LABEL: dont_widen_undef(
|
||||
; CHECK: %m.011 = phi i32 [ 33, %entry ], [ 0, %block1 ]
|
||||
; CHECK-NEXT: %cmp.i = icmp ugt i32 %m.011, 1
|
||||
; CHECK: %cmp.i = phi i1 [ false, %block1 ], [ true, %entry ]
|
||||
; CHECK-NEXT: %m.011 = phi i32 [ 0, %block1 ], [ 33, %entry ]
|
||||
; CHECK-NEXT: %m.1.op = lshr i32 1, %m.011
|
||||
; CHECK-NEXT: %sext.mask = and i32 %m.1.op, 65535
|
||||
; CHECK-NEXT: %cmp115 = icmp ne i32 %sext.mask, 0
|
||||
|
Loading…
Reference in New Issue
Block a user