mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[InstCombine] add folds for unsigned-overflow compares
Name: op_ugt_sum %a = add i8 %x, %y %r = icmp ugt i8 %x, %a => %notx = xor i8 %x, -1 %r = icmp ugt i8 %y, %notx Name: sum_ult_op %a = add i8 %x, %y %r = icmp ult i8 %a, %x => %notx = xor i8 %x, -1 %r = icmp ugt i8 %y, %notx https://rise4fun.com/Alive/ZRxI AFAICT, this doesn't interfere with any add-saturation patterns because those have >1 use for the 'add'. But this should be better for IR analysis and codegen in the basic cases. This is another fold inspired by PR14613: https://bugs.llvm.org/show_bug.cgi?id=14613 llvm-svn: 342004
This commit is contained in:
parent
43a811852d
commit
02e2e1a226
@ -3047,6 +3047,18 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) {
|
||||
return nullptr;
|
||||
|
||||
const CmpInst::Predicate Pred = I.getPredicate();
|
||||
Value *X;
|
||||
|
||||
// Convert add-with-unsigned-overflow comparisons into a 'not' with compare.
|
||||
// (Op1 + X) <u Op1 --> ~Op1 <u X
|
||||
// Op0 >u (Op0 + X) --> X >u ~Op0
|
||||
if (match(Op0, m_OneUse(m_c_Add(m_Specific(Op1), m_Value(X)))) &&
|
||||
Pred == ICmpInst::ICMP_ULT)
|
||||
return new ICmpInst(Pred, Builder.CreateNot(Op1), X);
|
||||
if (match(Op1, m_OneUse(m_c_Add(m_Specific(Op0), m_Value(X)))) &&
|
||||
Pred == ICmpInst::ICMP_UGT)
|
||||
return new ICmpInst(Pred, X, Builder.CreateNot(Op0));
|
||||
|
||||
bool NoOp0WrapProblem = false, NoOp1WrapProblem = false;
|
||||
if (BO0 && isa<OverflowingBinaryOperator>(BO0))
|
||||
NoOp0WrapProblem =
|
||||
|
@ -377,8 +377,8 @@ define i1 @op_ugt_sum_commute1(i8 %p1, i8 %p2) {
|
||||
; CHECK-LABEL: @op_ugt_sum_commute1(
|
||||
; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
|
||||
; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
|
||||
; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], [[Y]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X]], [[A]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], -1
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
|
||||
; CHECK-NEXT: ret i1 [[C]]
|
||||
;
|
||||
%x = sdiv i8 42, %p1
|
||||
@ -392,8 +392,8 @@ define <2 x i1> @op_ugt_sum_vec_commute2(<2 x i8> %p1, <2 x i8> %p2) {
|
||||
; CHECK-LABEL: @op_ugt_sum_vec_commute2(
|
||||
; CHECK-NEXT: [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
|
||||
; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P2:%.*]]
|
||||
; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[X]], [[A]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X]], <i8 -1, i8 -1>
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[C]]
|
||||
;
|
||||
%x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
|
||||
@ -424,8 +424,8 @@ define <2 x i1> @sum_ult_op_vec_commute1(<2 x i8> %p1, <2 x i8> %p2) {
|
||||
; CHECK-LABEL: @sum_ult_op_vec_commute1(
|
||||
; CHECK-NEXT: [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
|
||||
; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i8> <i8 -42, i8 42>, [[P2:%.*]]
|
||||
; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[X]], [[Y]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[A]], [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X]], <i8 -1, i8 -1>
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[C]]
|
||||
;
|
||||
%x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
|
||||
@ -439,8 +439,8 @@ define i1 @sum_ult_op_commute2(i8 %p1, i8 %p2) {
|
||||
; CHECK-LABEL: @sum_ult_op_commute2(
|
||||
; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
|
||||
; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
|
||||
; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[A]], [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], -1
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
|
||||
; CHECK-NEXT: ret i1 [[C]]
|
||||
;
|
||||
%x = sdiv i8 42, %p1
|
||||
|
Loading…
Reference in New Issue
Block a user