1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[InstCombine] Remove one use restriction on the shift for calls to foldICmpAndShift.

If this transformation succeeds, we're going to remove our dependency on the shift by rewriting the and. So it doesn't matter how many uses the shift has.

This distributes the one use check to other transforms in foldICmpAndConstConst that do need it.

Differential Revision: https://reviews.llvm.org/D38206

llvm-svn: 314233
This commit is contained in:
Craig Topper 2017-09-26 18:47:25 +00:00
parent f05301ced0
commit 652ef79124
2 changed files with 22 additions and 3 deletions

View File

@ -1646,7 +1646,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
if (!match(And->getOperand(1), m_APInt(C2)))
return nullptr;
if (!And->hasOneUse() || !And->getOperand(0)->hasOneUse())
if (!And->hasOneUse())
return nullptr;
// If the LHS is an 'and' of a truncate and we can widen the and/compare to
@ -1658,7 +1658,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
// set or if it is an equality comparison. Extending a relational comparison
// when we're checking the sign bit would not work.
Value *W;
if (match(And->getOperand(0), m_Trunc(m_Value(W))) &&
if (match(And->getOperand(0), m_OneUse(m_Trunc(m_Value(W)))) &&
(Cmp.isEquality() || (!C1->isNegative() && !C2->isNegative()))) {
// TODO: Is this a good transform for vectors? Wider types may reduce
// throughput. Should this transform be limited (even for scalars) by using
@ -1680,7 +1680,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
// (icmp pred (and A, (or (shl 1, B), 1), 0))
//
// iff pred isn't signed
if (!Cmp.isSigned() && C1->isNullValue() &&
if (!Cmp.isSigned() && C1->isNullValue() && And->getOperand(0)->hasOneUse() &&
match(And->getOperand(1), m_One())) {
Constant *One = cast<Constant>(And->getOperand(1));
Value *Or = And->getOperand(0);

View File

@ -1615,6 +1615,25 @@ define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
ret <2 x i1> %tobool
}
; Variation of the above with an extra use of the shift
define i1 @icmp_and_shr_multiuse(i32 %X) {
; CHECK-LABEL: @icmp_and_shr_multiuse(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
; CHECK-NEXT: ret i1 [[AND3]]
;
%shr = lshr i32 %X, 4
%and = and i32 %shr, 15
%and2 = and i32 %shr, 31 ; second use of the shift
%tobool = icmp ne i32 %and, 14
%tobool2 = icmp ne i32 %and2, 27
%and3 = and i1 %tobool, %tobool2
ret i1 %and3
}
; PR16244
define i1 @test71(i8* %x) {
; CHECK-LABEL: @test71(