mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
InstCombine: Teach icmp merging about the equivalence of bit tests and UGE/ULT with a power of 2.
This happens in bitfield code. While there reorganize the existing code a bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201176 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
75bf592807
commit
1e6240a85d
@ -503,31 +503,46 @@ static unsigned conjugateICmpMask(unsigned Mask) {
|
||||
/// decomposition fails.
|
||||
static bool decomposeBitTestICmp(const ICmpInst *I, ICmpInst::Predicate &Pred,
|
||||
Value *&X, Value *&Y, Value *&Z) {
|
||||
// X < 0 is equivalent to (X & SignBit) != 0.
|
||||
if (I->getPredicate() == ICmpInst::ICMP_SLT)
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1)))
|
||||
if (C->isZero()) {
|
||||
X = I->getOperand(0);
|
||||
Y = ConstantInt::get(I->getContext(),
|
||||
APInt::getSignBit(C->getBitWidth()));
|
||||
Pred = ICmpInst::ICMP_NE;
|
||||
Z = C;
|
||||
return true;
|
||||
}
|
||||
ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1));
|
||||
if (!C)
|
||||
return false;
|
||||
|
||||
// X > -1 is equivalent to (X & SignBit) == 0.
|
||||
if (I->getPredicate() == ICmpInst::ICMP_SGT)
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1)))
|
||||
if (C->isAllOnesValue()) {
|
||||
X = I->getOperand(0);
|
||||
Y = ConstantInt::get(I->getContext(),
|
||||
APInt::getSignBit(C->getBitWidth()));
|
||||
Pred = ICmpInst::ICMP_EQ;
|
||||
Z = ConstantInt::getNullValue(C->getType());
|
||||
return true;
|
||||
}
|
||||
switch (I->getPredicate()) {
|
||||
default:
|
||||
return false;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
// X < 0 is equivalent to (X & SignBit) != 0.
|
||||
if (!C->isZero())
|
||||
return false;
|
||||
Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
|
||||
Pred = ICmpInst::ICMP_NE;
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
// X > -1 is equivalent to (X & SignBit) == 0.
|
||||
if (!C->isAllOnesValue())
|
||||
return false;
|
||||
Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
|
||||
Pred = ICmpInst::ICMP_EQ;
|
||||
break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
// X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
|
||||
if (!C->getValue().isPowerOf2())
|
||||
return false;
|
||||
Y = ConstantInt::get(I->getContext(), -C->getValue());
|
||||
Pred = ICmpInst::ICMP_EQ;
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
// X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
|
||||
if (!(C->getValue() + 1).isPowerOf2())
|
||||
return false;
|
||||
Y = ConstantInt::get(I->getContext(), ~C->getValue());
|
||||
Pred = ICmpInst::ICMP_NE;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
X = I->getOperand(0);
|
||||
Z = ConstantInt::getNullValue(C->getType());
|
||||
return true;
|
||||
}
|
||||
|
||||
/// foldLogOpOfMaskedICmpsHelper:
|
||||
|
@ -177,3 +177,41 @@ if.then:
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test10(i32 %a) nounwind {
|
||||
%1 = and i32 %a, 2
|
||||
%2 = icmp eq i32 %1, 0
|
||||
%3 = icmp ult i32 %a, 4
|
||||
%or.cond = and i1 %2, %3
|
||||
br i1 %or.cond, label %if.then, label %if.end
|
||||
|
||||
; CHECK-LABEL: @test10(
|
||||
; CHECK-NEXT: %1 = icmp ult i32 %a, 2
|
||||
; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @foo() nounwind
|
||||
ret void
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test11(i32 %a) nounwind {
|
||||
%1 = and i32 %a, 2
|
||||
%2 = icmp ne i32 %1, 0
|
||||
%3 = icmp ugt i32 %a, 3
|
||||
%or.cond = or i1 %2, %3
|
||||
br i1 %or.cond, label %if.then, label %if.end
|
||||
|
||||
; CHECK-LABEL: @test11(
|
||||
; CHECK-NEXT: %1 = icmp ugt i32 %a, 1
|
||||
; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @foo() nounwind
|
||||
ret void
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user