mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
InstCombine: allow unmasked icmps to be combined with logical ops
"(icmp op i8 A, B)" is equivalent to "(icmp op i8 (A & 0xff), B)" as a degenerate case. Allowing this as a "masked" comparison when analysing "(icmp) &/| (icmp)" allows us to combine them in more cases. rdar://problem/7625728 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189931 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7bfabdac4e
commit
0415b1810b
@ -568,14 +568,22 @@ static unsigned foldLogOpOfMaskedICmpsHelper(Value*& A,
|
|||||||
L21 = L22 = L1 = 0;
|
L21 = L22 = L1 = 0;
|
||||||
} else {
|
} else {
|
||||||
// Look for ANDs in the LHS icmp.
|
// Look for ANDs in the LHS icmp.
|
||||||
if (match(L1, m_And(m_Value(L11), m_Value(L12)))) {
|
if (!L1->getType()->isIntegerTy()) {
|
||||||
if (!match(L2, m_And(m_Value(L21), m_Value(L22))))
|
// You can icmp pointers, for example. They really aren't masks.
|
||||||
L21 = L22 = 0;
|
L11 = L12 = 0;
|
||||||
} else {
|
} else if (!match(L1, m_And(m_Value(L11), m_Value(L12)))) {
|
||||||
if (!match(L2, m_And(m_Value(L11), m_Value(L12))))
|
// Any icmp can be viewed as being trivially masked; if it allows us to
|
||||||
return 0;
|
// remove one, it's worth it.
|
||||||
std::swap(L1, L2);
|
L11 = L1;
|
||||||
|
L12 = Constant::getAllOnesValue(L1->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!L2->getType()->isIntegerTy()) {
|
||||||
|
// You can icmp pointers, for example. They really aren't masks.
|
||||||
L21 = L22 = 0;
|
L21 = L22 = 0;
|
||||||
|
} else if (!match(L2, m_And(m_Value(L21), m_Value(L22)))) {
|
||||||
|
L21 = L2;
|
||||||
|
L22 = Constant::getAllOnesValue(L2->getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +604,14 @@ static unsigned foldLogOpOfMaskedICmpsHelper(Value*& A,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
E = R2; R1 = 0; ok = true;
|
E = R2; R1 = 0; ok = true;
|
||||||
} else if (match(R1, m_And(m_Value(R11), m_Value(R12)))) {
|
} else if (R1->getType()->isIntegerTy()) {
|
||||||
|
if (!match(R1, m_And(m_Value(R11), m_Value(R12)))) {
|
||||||
|
// As before, model no mask as a trivial mask if it'll let us do an
|
||||||
|
// optimisation.
|
||||||
|
R11 = R1;
|
||||||
|
R12 = Constant::getAllOnesValue(R1->getType());
|
||||||
|
}
|
||||||
|
|
||||||
if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
|
if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
|
||||||
A = R11; D = R12; E = R2; ok = true;
|
A = R11; D = R12; E = R2; ok = true;
|
||||||
} else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
|
} else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
|
||||||
@ -609,7 +624,12 @@ static unsigned foldLogOpOfMaskedICmpsHelper(Value*& A,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Look for ANDs in on the right side of the RHS icmp.
|
// Look for ANDs in on the right side of the RHS icmp.
|
||||||
if (!ok && match(R2, m_And(m_Value(R11), m_Value(R12)))) {
|
if (!ok && R2->getType()->isIntegerTy()) {
|
||||||
|
if (!match(R2, m_And(m_Value(R11), m_Value(R12)))) {
|
||||||
|
R11 = R2;
|
||||||
|
R12 = Constant::getAllOnesValue(R2->getType());
|
||||||
|
}
|
||||||
|
|
||||||
if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
|
if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
|
||||||
A = R11; D = R12; E = R1; ok = true;
|
A = R11; D = R12; E = R1; ok = true;
|
||||||
} else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
|
} else if (R12 == L11 || R12 == L12 || R12 == L21 || R12 == L22) {
|
||||||
|
@ -120,3 +120,33 @@ define i1 @masked_or_allzeroes_notoptimised(i32 %A) {
|
|||||||
ret i1 %res
|
ret i1 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i1 @nomask_lhs(i32 %in) {
|
||||||
|
; CHECK-LABEL: @nomask_lhs
|
||||||
|
; CHECK: [[MASK:%.*]] = and i32 %in, 1
|
||||||
|
; CHECK: icmp eq i32 [[MASK]], 0
|
||||||
|
; CHECK-NOT: icmp
|
||||||
|
; CHECK: ret i1
|
||||||
|
%tst1 = icmp eq i32 %in, 0
|
||||||
|
|
||||||
|
%masked = and i32 %in, 1
|
||||||
|
%tst2 = icmp eq i32 %masked, 0
|
||||||
|
|
||||||
|
%val = or i1 %tst1, %tst2
|
||||||
|
ret i1 %val
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define i1 @nomask_rhs(i32 %in) {
|
||||||
|
; CHECK-LABEL: @nomask_rhs
|
||||||
|
; CHECK: [[MASK:%.*]] = and i32 %in, 1
|
||||||
|
; CHECK: icmp eq i32 [[MASK]], 0
|
||||||
|
; CHECK-NOT: icmp
|
||||||
|
; CHECK: ret i1
|
||||||
|
%masked = and i32 %in, 1
|
||||||
|
%tst1 = icmp eq i32 %masked, 0
|
||||||
|
|
||||||
|
%tst2 = icmp eq i32 %in, 0
|
||||||
|
|
||||||
|
%val = or i1 %tst1, %tst2
|
||||||
|
ret i1 %val
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user