mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-09 10:55:03 +00:00
[InstCombine] canonicalize abs pattern
Differential Revision: https://reviews.llvm.org/D48754 llvm-svn: 338092
This commit is contained in:
parent
be97297545
commit
567485a72f
@ -794,8 +794,11 @@ canonicalizeMinMaxWithConstant(SelectInst &Sel, ICmpInst &Cmp,
|
||||
return &Sel;
|
||||
}
|
||||
|
||||
/// There are 4 select variants for each of ABS/NABS (different compare
|
||||
/// constants, compare predicates, select operands). Canonicalize to 1 pattern.
|
||||
/// There are many select variants for each of ABS/NABS.
|
||||
/// In matchSelectPattern(), there are different compare constants, compare
|
||||
/// predicates/operands and select operands.
|
||||
/// In isKnownNegation(), there are different formats of negated operands.
|
||||
/// Canonicalize all these variants to 1 pattern.
|
||||
/// This makes CSE more likely.
|
||||
static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
|
||||
InstCombiner::BuilderTy &Builder) {
|
||||
@ -810,34 +813,61 @@ static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
|
||||
if (SPF != SelectPatternFlavor::SPF_ABS &&
|
||||
SPF != SelectPatternFlavor::SPF_NABS)
|
||||
return nullptr;
|
||||
|
||||
// TODO: later canonicalization change will move this condition check.
|
||||
// Without this check, following assert will be hit.
|
||||
if (match(Cmp.getOperand(0), m_Sub(m_Value(), m_Value())))
|
||||
return nullptr;
|
||||
|
||||
// Is this already canonical?
|
||||
if (match(Cmp.getOperand(1), m_ZeroInt()) &&
|
||||
Cmp.getPredicate() == ICmpInst::ICMP_SLT)
|
||||
return nullptr;
|
||||
|
||||
// Create the canonical compare.
|
||||
Cmp.setPredicate(ICmpInst::ICMP_SLT);
|
||||
Cmp.setOperand(1, ConstantInt::getNullValue(Cmp.getOperand(0)->getType()));
|
||||
|
||||
// If the select operands do not change, we're done.
|
||||
Value *TVal = Sel.getTrueValue();
|
||||
Value *FVal = Sel.getFalseValue();
|
||||
assert(isKnownNegation(TVal, FVal) &&
|
||||
"Unexpected result from matchSelectPattern");
|
||||
|
||||
// The compare may use the negated abs()/nabs() operand, or it may use
|
||||
// negation in non-canonical form such as: sub A, B.
|
||||
bool CmpUsesNegatedOp = match(Cmp.getOperand(0), m_Neg(m_Specific(TVal))) ||
|
||||
match(Cmp.getOperand(0), m_Neg(m_Specific(FVal)));
|
||||
|
||||
bool CmpCanonicalized = !CmpUsesNegatedOp &&
|
||||
match(Cmp.getOperand(1), m_ZeroInt()) &&
|
||||
Cmp.getPredicate() == ICmpInst::ICMP_SLT;
|
||||
bool RHSCanonicalized = match(RHS, m_Neg(m_Specific(LHS)));
|
||||
|
||||
// Is this already canonical?
|
||||
if (CmpCanonicalized && RHSCanonicalized)
|
||||
return nullptr;
|
||||
|
||||
// If RHS is used by other instructions except compare and select, don't
|
||||
// canonicalize it to not increase the instruction count.
|
||||
if (!(RHS->hasOneUse() || (RHS->hasNUses(2) && CmpUsesNegatedOp)))
|
||||
return nullptr;
|
||||
|
||||
// Create the canonical compare: icmp slt LHS 0.
|
||||
if (!CmpCanonicalized) {
|
||||
Cmp.setPredicate(ICmpInst::ICMP_SLT);
|
||||
Cmp.setOperand(1, ConstantInt::getNullValue(Cmp.getOperand(0)->getType()));
|
||||
if (CmpUsesNegatedOp)
|
||||
Cmp.setOperand(0, LHS);
|
||||
}
|
||||
|
||||
// Create the canonical RHS: RHS = sub (0, LHS).
|
||||
if (!RHSCanonicalized) {
|
||||
assert(RHS->hasOneUse() && "RHS use number is not right");
|
||||
RHS = Builder.CreateNeg(LHS);
|
||||
if (TVal == LHS) {
|
||||
Sel.setFalseValue(RHS);
|
||||
FVal = RHS;
|
||||
} else {
|
||||
Sel.setTrueValue(RHS);
|
||||
TVal = RHS;
|
||||
}
|
||||
}
|
||||
|
||||
// If the select operands do not change, we're done.
|
||||
if (SPF == SelectPatternFlavor::SPF_NABS) {
|
||||
if (TVal == LHS && match(FVal, m_Neg(m_Specific(TVal))))
|
||||
if (TVal == LHS)
|
||||
return &Sel;
|
||||
assert(FVal == LHS && match(TVal, m_Neg(m_Specific(FVal))) &&
|
||||
"Unexpected results from matchSelectPattern");
|
||||
assert(FVal == LHS && "Unexpected results from matchSelectPattern");
|
||||
} else {
|
||||
if (FVal == LHS && match(TVal, m_Neg(m_Specific(FVal))))
|
||||
if (FVal == LHS)
|
||||
return &Sel;
|
||||
assert(TVal == LHS && match(FVal, m_Neg(m_Specific(TVal))) &&
|
||||
"Unexpected results from matchSelectPattern");
|
||||
assert(TVal == LHS && "Unexpected results from matchSelectPattern");
|
||||
}
|
||||
|
||||
// We are swapping the select operands, so swap the metadata too.
|
||||
|
@ -134,9 +134,9 @@ define i32 @abs_canonical_5(i8 %x) {
|
||||
define i32 @abs_canonical_6(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @abs_canonical_6(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[TMP2]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP2]], i32 [[TMP1]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp1 = sub i32 %a, %b
|
||||
@ -149,9 +149,9 @@ define i32 @abs_canonical_6(i32 %a, i32 %b) {
|
||||
define <2 x i8> @abs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
|
||||
; CHECK-LABEL: @abs_canonical_7(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[TMP1]], <i8 -1, i8 -1>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP2]], <2 x i8> [[TMP1]]
|
||||
; CHECK-NEXT: ret <2 x i8> [[ABS]]
|
||||
;
|
||||
|
||||
@ -165,8 +165,8 @@ define <2 x i8> @abs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
|
||||
define i32 @abs_canonical_8(i32 %a) {
|
||||
; CHECK-LABEL: @abs_canonical_8(
|
||||
; CHECK-NEXT: [[TMP:%.*]] = sub i32 0, [[A:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP]], 0
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[TMP]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP]], i32 [[A]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp = sub i32 0, %a
|
||||
@ -175,6 +175,38 @@ define i32 @abs_canonical_8(i32 %a) {
|
||||
ret i32 %abs
|
||||
}
|
||||
|
||||
define i32 @abs_canonical_9(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @abs_canonical_9(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[TMP2]]
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[ABS]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i32 [[ADD]]
|
||||
;
|
||||
%tmp1 = sub i32 %a, %b
|
||||
%cmp = icmp sgt i32 %tmp1, -1
|
||||
%tmp2 = sub i32 %b, %a
|
||||
%abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
|
||||
%add = add i32 %abs, %tmp2 ; increase use count for %tmp2.
|
||||
ret i32 %add
|
||||
}
|
||||
|
||||
define i32 @abs_canonical_10(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @abs_canonical_10(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: [[NEGTMP:%.*]] = sub i32 0, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGTMP]], i32 [[TMP1]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp2 = sub i32 %b, %a
|
||||
%tmp1 = sub i32 %a, %b
|
||||
%cmp = icmp sgt i32 %tmp1, -1
|
||||
%abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
|
||||
ret i32 %abs
|
||||
}
|
||||
|
||||
; We have a canonical form of nabs to make CSE easier.
|
||||
|
||||
define i8 @nabs_canonical_1(i8 %x) {
|
||||
@ -266,9 +298,9 @@ define i32 @nabs_canonical_5(i8 %x) {
|
||||
define i32 @nabs_canonical_6(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @nabs_canonical_6(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP2]], i32 [[TMP1]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[TMP2]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp1 = sub i32 %a, %b
|
||||
@ -281,9 +313,9 @@ define i32 @nabs_canonical_6(i32 %a, i32 %b) {
|
||||
define <2 x i8> @nabs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
|
||||
; CHECK-LABEL: @nabs_canonical_7(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[TMP1]], <i8 -1, i8 -1>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP2]], <2 x i8> [[TMP1]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]]
|
||||
; CHECK-NEXT: ret <2 x i8> [[ABS]]
|
||||
;
|
||||
%tmp1 = sub <2 x i8> %a, %b
|
||||
@ -296,8 +328,8 @@ define <2 x i8> @nabs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {
|
||||
define i32 @nabs_canonical_8(i32 %a) {
|
||||
; CHECK-LABEL: @nabs_canonical_8(
|
||||
; CHECK-NEXT: [[TMP:%.*]] = sub i32 0, [[A:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP]], 0
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP]], i32 [[A]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[TMP]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp = sub i32 0, %a
|
||||
@ -306,6 +338,38 @@ define i32 @nabs_canonical_8(i32 %a) {
|
||||
ret i32 %abs
|
||||
}
|
||||
|
||||
define i32 @nabs_canonical_9(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @nabs_canonical_9(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP1]], -1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[B]], [[A]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP2]], i32 [[TMP1]]
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP2]], [[ABS]]
|
||||
; CHECK-NEXT: ret i32 [[ADD]]
|
||||
;
|
||||
%tmp1 = sub i32 %a, %b
|
||||
%cmp = icmp sgt i32 %tmp1, -1
|
||||
%tmp2 = sub i32 %b, %a
|
||||
%abs = select i1 %cmp, i32 %tmp2, i32 %tmp1
|
||||
%add = add i32 %tmp2, %abs ; increase use count for %tmp2
|
||||
ret i32 %add
|
||||
}
|
||||
|
||||
define i32 @nabs_canonical_10(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @nabs_canonical_10(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: [[NEGTMP:%.*]] = sub i32 0, [[TMP1]]
|
||||
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[TMP1]], i32 [[NEGTMP]]
|
||||
; CHECK-NEXT: ret i32 [[ABS]]
|
||||
;
|
||||
%tmp2 = sub i32 %b, %a
|
||||
%tmp1 = sub i32 %a, %b
|
||||
%cmp = icmp slt i32 %tmp1, 1
|
||||
%abs = select i1 %cmp, i32 %tmp1, i32 %tmp2
|
||||
ret i32 %abs
|
||||
}
|
||||
|
||||
; The following 5 tests use a shift+add+xor to implement abs():
|
||||
; B = ashr i8 A, 7 -- smear the sign bit.
|
||||
; xor (add A, B), B -- add -1 and flip bits if negative
|
||||
|
@ -289,11 +289,11 @@ define i32 @abs_abs_x16(i32 %x) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; abs(abs(-x)) -> abs(-x)
|
||||
; abs(abs(-x)) -> abs(-x) -> abs(x)
|
||||
define i32 @abs_abs_x17(i32 %x) {
|
||||
; CHECK-LABEL: @abs_abs_x17(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], -1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[X]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
@ -310,9 +310,9 @@ define i32 @abs_abs_x17(i32 %x) {
|
||||
define i32 @abs_abs_x18(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @abs_abs_x18(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -1
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[NEGA]], i32 [[A]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
%a = sub nsw i32 %x, %y
|
||||
@ -325,11 +325,11 @@ define i32 @abs_abs_x18(i32 %x, i32 %y) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; abs(abs(-x)) -> abs(-x)
|
||||
; abs(abs(-x)) -> abs(-x) -> abs(x)
|
||||
define <2 x i32> @abs_abs_x02_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @abs_abs_x02_vec(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[SUB]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
@ -346,9 +346,9 @@ define <2 x i32> @abs_abs_x02_vec(<2 x i32> %x) {
|
||||
define <2 x i32> @abs_abs_x03_vec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @abs_abs_x03_vec(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw <2 x i32> [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw <2 x i32> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[A]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[A]], <2 x i32> [[B]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[A]], zeroinitializer
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i32> zeroinitializer, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[NEGA]], <2 x i32> [[A]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
%a = sub nsw <2 x i32> %x, %y
|
||||
@ -617,11 +617,11 @@ define i32 @nabs_nabs_x16(i32 %x) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; nabs(nabs(-x)) -> nabs(-x)
|
||||
; nabs(nabs(-x)) -> nabs(-x) -> nabs(x)
|
||||
define i32 @nabs_nabs_x17(i32 %x) {
|
||||
; CHECK-LABEL: @nabs_nabs_x17(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], -1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
@ -638,9 +638,9 @@ define i32 @nabs_nabs_x17(i32 %x) {
|
||||
define i32 @nabs_nabs_x18(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @nabs_nabs_x18(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -1
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[NEGA]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
%a = sub nsw i32 %x, %y
|
||||
@ -653,11 +653,11 @@ define i32 @nabs_nabs_x18(i32 %x, i32 %y) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; nabs(nabs(-x)) -> nabs(-x)
|
||||
; nabs(nabs(-x)) -> nabs(-x) -> nabs(x)
|
||||
define <2 x i32> @nabs_nabs_x01_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @nabs_nabs_x01_vec(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[SUB]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[X]], <2 x i32> [[SUB]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
@ -674,9 +674,9 @@ define <2 x i32> @nabs_nabs_x01_vec(<2 x i32> %x) {
|
||||
define <2 x i32> @nabs_nabs_x02_vec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @nabs_nabs_x02_vec(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw <2 x i32> [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw <2 x i32> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[A]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[B]], <2 x i32> [[A]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[A]], zeroinitializer
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i32> zeroinitializer, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[A]], <2 x i32> [[NEGA]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
%a = sub nsw <2 x i32> %x, %y
|
||||
@ -945,11 +945,11 @@ define i32 @abs_nabs_x16(i32 %x) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; abs(nabs(-x)) -> abs(-x)
|
||||
; abs(nabs(-x)) -> abs(-x) -> abs(x)
|
||||
define i32 @abs_nabs_x17(i32 %x) {
|
||||
; CHECK-LABEL: @abs_nabs_x17(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], -1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[X]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
@ -966,9 +966,9 @@ define i32 @abs_nabs_x17(i32 %x) {
|
||||
define i32 @abs_nabs_x18(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @abs_nabs_x18(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -1
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[NEGA]], i32 [[A]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
%a = sub nsw i32 %x, %y
|
||||
@ -981,11 +981,11 @@ define i32 @abs_nabs_x18(i32 %x, i32 %y) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; abs(nabs(-x)) -> abs(-x)
|
||||
; abs(nabs(-x)) -> abs(-x) -> abs(x)
|
||||
define <2 x i32> @abs_nabs_x01_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @abs_nabs_x01_vec(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[SUB]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
@ -1002,9 +1002,9 @@ define <2 x i32> @abs_nabs_x01_vec(<2 x i32> %x) {
|
||||
define <2 x i32> @abs_nabs_x02_vec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @abs_nabs_x02_vec(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw <2 x i32> [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw <2 x i32> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[A]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[A]], <2 x i32> [[B]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[A]], zeroinitializer
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i32> zeroinitializer, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[NEGA]], <2 x i32> [[A]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
%a = sub nsw <2 x i32> %x, %y
|
||||
@ -1273,11 +1273,11 @@ define i32 @nabs_abs_x16(i32 %x) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; nabs(abs(-x)) -> nabs(-x)
|
||||
; nabs(abs(-x)) -> nabs(-x) -> nabs(x)
|
||||
define i32 @nabs_abs_x17(i32 %x) {
|
||||
; CHECK-LABEL: @nabs_abs_x17(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], -1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 0
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
@ -1294,9 +1294,9 @@ define i32 @nabs_abs_x17(i32 %x) {
|
||||
define i32 @nabs_abs_x18(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @nabs_abs_x18(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -1
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[NEGA]]
|
||||
; CHECK-NEXT: ret i32 [[COND]]
|
||||
;
|
||||
%a = sub nsw i32 %x, %y
|
||||
@ -1309,11 +1309,11 @@ define i32 @nabs_abs_x18(i32 %x, i32 %y) {
|
||||
ret i32 %cond18
|
||||
}
|
||||
|
||||
; nabs(abs(-x)) -> nabs(-x)
|
||||
; nabs(abs(-x)) -> nabs(-x) -> nabs(x)
|
||||
define <2 x i32> @nabs_abs_x01_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @nabs_abs_x01_vec(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[SUB]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[X]], <2 x i32> [[SUB]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
@ -1330,9 +1330,9 @@ define <2 x i32> @nabs_abs_x01_vec(<2 x i32> %x) {
|
||||
define <2 x i32> @nabs_abs_x02_vec(<2 x i32> %x, <2 x i32> %y) {
|
||||
; CHECK-LABEL: @nabs_abs_x02_vec(
|
||||
; CHECK-NEXT: [[A:%.*]] = sub nsw <2 x i32> [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[B:%.*]] = sub nsw <2 x i32> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[A]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[B]], <2 x i32> [[A]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[A]], zeroinitializer
|
||||
; CHECK-NEXT: [[NEGA:%.*]] = sub <2 x i32> zeroinitializer, [[A]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[A]], <2 x i32> [[NEGA]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
%a = sub nsw <2 x i32> %x, %y
|
||||
|
@ -3345,7 +3345,7 @@ define <2 x i1> @PR36583(<2 x i8*>) {
|
||||
define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @Op1Negated_Vec(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X:%.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[SUB]], <i32 -1, i32 -1>
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
|
||||
; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[SUB]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[COND]]
|
||||
;
|
||||
|
Loading…
x
Reference in New Issue
Block a user