mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-31 07:43:37 +00:00
[InstCombine] Transform A & (L - 1) u< L --> L != 0
Summary: This transform is never a pessimization at the IR level (since it replaces an `icmp` with another), and has potentiall payoffs: 1. It may make the `icmp` fold away or become loop invariant. 2. It may make the `A & (L - 1)` computation dead. This shows up in Java, in range checks generated by array accesses of the form `a[i & (a.length - 1)]`. Reviewers: reames, majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D12210 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245635 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9cd73adba0
commit
ba38902605
@ -3490,6 +3490,19 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BO0) {
|
||||
// Transform A & (L - 1) `ult` L --> L != 0
|
||||
Value *L;
|
||||
auto LSubOne = m_Add(m_Value(L), m_AllOnes());
|
||||
auto BitwiseAnd =
|
||||
m_CombineOr(m_And(m_Value(), LSubOne), m_And(LSubOne, m_Value()));
|
||||
|
||||
if (match(BO0, BitwiseAnd) && I.getPredicate() == ICmpInst::ICMP_ULT) {
|
||||
auto *Zero = Constant::getNullValue(BO0->getType());
|
||||
return new ICmpInst(ICmpInst::ICMP_NE, L, Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ Value *A, *B;
|
||||
|
@ -1603,3 +1603,23 @@ define i32 @f7(i32 %a, i32 %b) {
|
||||
%s = select i1 %cmp, i32 10000, i32 0
|
||||
ret i32 %s
|
||||
}
|
||||
|
||||
; CHECK: @f8(
|
||||
; CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = icmp ne i32 %lim, 0
|
||||
; CHECK-NEXT: ret i1 [[RESULT]]
|
||||
define i1 @f8(i32 %val, i32 %lim) {
|
||||
%lim.sub = add i32 %lim, -1
|
||||
%val.and = and i32 %val, %lim.sub
|
||||
%r = icmp ult i32 %val.and, %lim
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; CHECK: @f9(
|
||||
; CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = icmp ne i32 %lim, 0
|
||||
; CHECK-NEXT: ret i1 [[RESULT]]
|
||||
define i1 @f9(i32 %val, i32 %lim) {
|
||||
%lim.sub = sub i32 %lim, 1
|
||||
%val.and = and i32 %val, %lim.sub
|
||||
%r = icmp ult i32 %val.and, %lim
|
||||
ret i1 %r
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user