mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 09:37:20 +00:00
InstSimplify: Move a transform from InstCombine to InstSimplify
Several combines involving icmp (shl C2, %X) C1 can be simplified without introducing any new instructions. Move them to InstSimplify; while we are at it, make them more powerful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216642 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4a76317ebb
commit
b11fff1d8a
@ -2388,6 +2388,41 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
return getTrue(ITy);
|
||||
}
|
||||
|
||||
// handle:
|
||||
// CI2 << X == CI
|
||||
// CI2 << X != CI
|
||||
//
|
||||
// where CI2 is a power of 2 and CI isn't
|
||||
if (auto *CI = dyn_cast<ConstantInt>(RHS)) {
|
||||
const APInt *CI2Val, *CIVal = &CI->getValue();
|
||||
if (LBO && match(LBO, m_Shl(m_APInt(CI2Val), m_Value())) &&
|
||||
CI2Val->isPowerOf2()) {
|
||||
if (!CIVal->isPowerOf2()) {
|
||||
// CI2 << X can equal zero in some circumstances,
|
||||
// this simplification is unsafe if CI is zero.
|
||||
//
|
||||
// We know it is safe if:
|
||||
// - The shift is nsw, we can't shift out the one bit.
|
||||
// - The shift is nuw, we can't shift out the one bit.
|
||||
// - CI2 is one
|
||||
// - CI isn't zero
|
||||
if (LBO->hasNoSignedWrap() || LBO->hasNoUnsignedWrap() ||
|
||||
*CI2Val == 1 || !CI->isZero()) {
|
||||
if (Pred == ICmpInst::ICMP_EQ)
|
||||
return ConstantInt::getFalse(RHS->getContext());
|
||||
if (Pred == ICmpInst::ICMP_NE)
|
||||
return ConstantInt::getTrue(RHS->getContext());
|
||||
}
|
||||
}
|
||||
if (CIVal->isSignBit() && *CI2Val == 1) {
|
||||
if (Pred == ICmpInst::ICMP_UGT)
|
||||
return ConstantInt::getFalse(RHS->getContext());
|
||||
if (Pred == ICmpInst::ICMP_ULE)
|
||||
return ConstantInt::getTrue(RHS->getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxRecurse && LBO && RBO && LBO->getOpcode() == RBO->getOpcode() &&
|
||||
LBO->getOperand(1) == RBO->getOperand(1)) {
|
||||
switch (LBO->getOpcode()) {
|
||||
|
@ -1503,16 +1503,10 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
unsigned RHSLog2 = RHSV.logBase2();
|
||||
|
||||
// (1 << X) >= 2147483648 -> X >= 31 -> X == 31
|
||||
// (1 << X) > 2147483648 -> X > 31 -> false
|
||||
// (1 << X) <= 2147483648 -> X <= 31 -> true
|
||||
// (1 << X) < 2147483648 -> X < 31 -> X != 31
|
||||
if (RHSLog2 == TypeBits-1) {
|
||||
if (Pred == ICmpInst::ICMP_UGE)
|
||||
Pred = ICmpInst::ICMP_EQ;
|
||||
else if (Pred == ICmpInst::ICMP_UGT)
|
||||
return ReplaceInstUsesWith(ICI, Builder->getFalse());
|
||||
else if (Pred == ICmpInst::ICMP_ULE)
|
||||
return ReplaceInstUsesWith(ICI, Builder->getTrue());
|
||||
else if (Pred == ICmpInst::ICMP_ULT)
|
||||
Pred = ICmpInst::ICMP_NE;
|
||||
}
|
||||
@ -1547,10 +1541,6 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
if (RHSVIsPowerOf2)
|
||||
return new ICmpInst(
|
||||
Pred, X, ConstantInt::get(RHS->getType(), RHSV.logBase2()));
|
||||
|
||||
return ReplaceInstUsesWith(
|
||||
ICI, Pred == ICmpInst::ICMP_EQ ? Builder->getFalse()
|
||||
: Builder->getTrue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1148,22 +1148,6 @@ define i1 @icmp_shl_1_V_eq_32(i32 %V) {
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_eq_31(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
define i1 @icmp_shl_1_V_eq_31(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp eq i32 %shl, 31
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ne_31(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
define i1 @icmp_shl_1_V_ne_31(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ne i32 %shl, 31
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ult_30(
|
||||
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %V, 5
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
@ -1209,22 +1193,6 @@ define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ugt_2147483648(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
define i1 @icmp_shl_1_V_ugt_2147483648(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ugt i32 %shl, 2147483648
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ule_2147483648(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
define i1 @icmp_shl_1_V_ule_2147483648(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ule i32 %shl, 2147483648
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
|
||||
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %V, 31
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
|
@ -333,14 +333,46 @@ define i1 @or(i32 %x) {
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @shl(i32 %x) {
|
||||
; CHECK-LABEL: @shl(
|
||||
define i1 @shl1(i32 %x) {
|
||||
; CHECK-LABEL: @shl1(
|
||||
%s = shl i32 1, %x
|
||||
%c = icmp eq i32 %s, 0
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @shl2(i32 %X) {
|
||||
; CHECK: @shl2
|
||||
%sub = shl nsw i32 -1, %X
|
||||
%cmp = icmp eq i32 %sub, 31
|
||||
ret i1 %cmp
|
||||
; CHECK-NEXT: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @shl3(i32 %X) {
|
||||
; CHECK: @shl3
|
||||
%sub = shl nuw i32 4, %X
|
||||
%cmp = icmp eq i32 %sub, 31
|
||||
ret i1 %cmp
|
||||
; CHECK-NEXT: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @shl4(i32 %X) {
|
||||
; CHECK: @shl4
|
||||
%sub = shl nsw i32 -1, %X
|
||||
%cmp = icmp sle i32 %sub, -1
|
||||
ret i1 %cmp
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @shl5(i32 %X) {
|
||||
; CHECK: @shl5
|
||||
%sub = shl nuw i32 4, %X
|
||||
%cmp = icmp ugt i32 %sub, 3
|
||||
ret i1 %cmp
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @lshr1(i32 %x) {
|
||||
; CHECK-LABEL: @lshr1(
|
||||
%s = lshr i32 -1, %x
|
||||
@ -1009,3 +1041,39 @@ define i1 @icmp_shl_nsw_1(i64 %a) {
|
||||
; CHECK-LABEL: @icmp_shl_nsw_1
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @icmp_shl_1_V_ugt_2147483648(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ugt i32 %shl, 2147483648
|
||||
ret i1 %cmp
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ugt_2147483648(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @icmp_shl_1_V_ule_2147483648(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ule i32 %shl, 2147483648
|
||||
ret i1 %cmp
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ule_2147483648(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @icmp_shl_1_V_eq_31(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp eq i32 %shl, 31
|
||||
ret i1 %cmp
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_eq_31(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @icmp_shl_1_V_ne_31(i32 %V) {
|
||||
%shl = shl i32 1, %V
|
||||
%cmp = icmp ne i32 %shl, 31
|
||||
ret i1 %cmp
|
||||
|
||||
; CHECK-LABEL: @icmp_shl_1_V_ne_31(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user