mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[InstCombine] Non-canonical clamp-like pattern handling
Summary: Given a pattern like: ``` %old_cmp1 = icmp slt i32 %x, C2 %old_replacement = select i1 %old_cmp1, i32 %target_low, i32 %target_high %old_x_offseted = add i32 %x, C1 %old_cmp0 = icmp ult i32 %old_x_offseted, C0 %r = select i1 %old_cmp0, i32 %x, i32 %old_replacement ``` it can be rewritten as more canonical pattern: ``` %new_cmp1 = icmp slt i32 %x, -C1 %new_cmp2 = icmp sge i32 %x, C0-C1 %new_clamped_low = select i1 %new_cmp1, i32 %target_low, i32 %x %r = select i1 %new_cmp2, i32 %target_high, i32 %new_clamped_low ``` Iff `-C1 s<= C2 s<= C0-C1` Also, `ULT` predicate can also be `UGE`; or `UGT` iff `C0 != -1` (+invert result) Also, `SLT` predicate can also be `SGE`; or `SGT` iff `C2 != INT_MAX` (+invert result) If `C1 == 0`, then all 3 instructions must be one-use; else at most either `%old_cmp1` or `%old_x_offseted` can have extra uses. NOTE: if we could reuse `%old_cmp1` as one of the comparisons we'll have to build, this could be less limiting. So there are two icmp's, each one with 3 predicate variants, so there are 9 fold variants: | | ULT | UGE | UGT | | SLT | https://rise4fun.com/Alive/yIJ | https://rise4fun.com/Alive/5BfN | https://rise4fun.com/Alive/INH | | SGE | https://rise4fun.com/Alive/hd8 | https://rise4fun.com/Alive/Abk | https://rise4fun.com/Alive/PlzS | | SGT | https://rise4fun.com/Alive/VYG | https://rise4fun.com/Alive/oMY | https://rise4fun.com/Alive/KrzC | {F9730206} This fold was brought up in https://reviews.llvm.org/D65148#1603922 by @dmgreen, and is needed to unblock that patch. This patch requires D65530. Reviewers: spatel, nikic, xbolva00, dmgreen Reviewed By: spatel Subscribers: hiraditya, llvm-commits, dmgreen Tags: #llvm Differential Revision: https://reviews.llvm.org/D65765 llvm-svn: 368687
This commit is contained in:
parent
c08ef12796
commit
0648d2150a
@ -1118,6 +1118,149 @@ static Value *foldSelectValueEquivalence(SelectInst &Sel, ICmpInst &Cmp,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// See if this is a pattern like:
|
||||
// %old_cmp1 = icmp slt i32 %x, C2
|
||||
// %old_replacement = select i1 %old_cmp1, i32 %target_low, i32 %target_high
|
||||
// %old_x_offseted = add i32 %x, C1
|
||||
// %old_cmp0 = icmp ult i32 %old_x_offseted, C0
|
||||
// %r = select i1 %old_cmp0, i32 %x, i32 %old_replacement
|
||||
// This can be rewritten as more canonical pattern:
|
||||
// %new_cmp1 = icmp slt i32 %x, -C1
|
||||
// %new_cmp2 = icmp sge i32 %x, C0-C1
|
||||
// %new_clamped_low = select i1 %new_cmp1, i32 %target_low, i32 %x
|
||||
// %r = select i1 %new_cmp2, i32 %target_high, i32 %new_clamped_low
|
||||
// Iff -C1 s<= C2 s<= C0-C1
|
||||
// Also ULT predicate can also be UGT iff C0 != -1 (+invert result)
|
||||
// SLT predicate can also be SGT iff C2 != INT_MAX (+invert res.)
|
||||
static Instruction *canonicalizeClampLike(SelectInst &Sel0, ICmpInst &Cmp0,
|
||||
InstCombiner::BuilderTy &Builder) {
|
||||
Value *X = Sel0.getTrueValue();
|
||||
Value *Sel1 = Sel0.getFalseValue();
|
||||
|
||||
// First match the condition of the outermost select.
|
||||
// Said condition must be one-use.
|
||||
if (!Cmp0.hasOneUse())
|
||||
return nullptr;
|
||||
Value *Cmp00 = Cmp0.getOperand(0);
|
||||
Constant *C0;
|
||||
if (!match(Cmp0.getOperand(1),
|
||||
m_CombineAnd(m_AnyIntegralConstant(), m_Constant(C0))))
|
||||
return nullptr;
|
||||
// Canonicalize Cmp0 into the form we expect.
|
||||
// FIXME: we shouldn't care about lanes that are 'undef' in the end?
|
||||
switch (Cmp0.getPredicate()) {
|
||||
case ICmpInst::Predicate::ICMP_ULT:
|
||||
break; // Great!
|
||||
case ICmpInst::Predicate::ICMP_ULE:
|
||||
// We'd have to increment C0 by one, and for that it must not have all-ones
|
||||
// element, but then it would have been canonicalized to 'ult' before
|
||||
// we get here. So we can't do anything useful with 'ule'.
|
||||
return nullptr;
|
||||
case ICmpInst::Predicate::ICMP_UGT:
|
||||
// We want to canonicalize it to 'ult', so we'll need to increment C0,
|
||||
// which again means it must not have any all-ones elements.
|
||||
if (!match(C0,
|
||||
m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE,
|
||||
APInt::getAllOnesValue(
|
||||
C0->getType()->getScalarSizeInBits()))))
|
||||
return nullptr; // Can't do, have all-ones element[s].
|
||||
C0 = AddOne(C0);
|
||||
std::swap(X, Sel1);
|
||||
break;
|
||||
case ICmpInst::Predicate::ICMP_UGE:
|
||||
// The only way we'd get this predicate if this `icmp` has extra uses,
|
||||
// but then we won't be able to do this fold.
|
||||
return nullptr;
|
||||
default:
|
||||
return nullptr; // Unknown predicate.
|
||||
}
|
||||
|
||||
// Now that we've canonicalized the ICmp, we know the X we expect;
|
||||
// the select in other hand should be one-use.
|
||||
if (!Sel1->hasOneUse())
|
||||
return nullptr;
|
||||
|
||||
// We now can finish matching the condition of the outermost select:
|
||||
// it should either be the X itself, or an addition of some constant to X.
|
||||
Constant *C1;
|
||||
if (Cmp00 == X)
|
||||
C1 = ConstantInt::getNullValue(Sel0.getType());
|
||||
else if (!match(Cmp00,
|
||||
m_Add(m_Specific(X),
|
||||
m_CombineAnd(m_AnyIntegralConstant(), m_Constant(C1)))))
|
||||
return nullptr;
|
||||
|
||||
Value *Cmp1;
|
||||
ICmpInst::Predicate Pred1;
|
||||
Constant *C2;
|
||||
Value *ReplacementLow, *ReplacementHigh;
|
||||
if (!match(Sel1, m_Select(m_Value(Cmp1), m_Value(ReplacementLow),
|
||||
m_Value(ReplacementHigh))) ||
|
||||
!match(Cmp1,
|
||||
m_ICmp(Pred1, m_Specific(X),
|
||||
m_CombineAnd(m_AnyIntegralConstant(), m_Constant(C2)))))
|
||||
return nullptr;
|
||||
|
||||
if (!Cmp1->hasOneUse() && (Cmp00 == X || !Cmp00->hasOneUse()))
|
||||
return nullptr; // Not enough one-use instructions for the fold.
|
||||
// FIXME: this restriction could be relaxed if Cmp1 can be reused as one of
|
||||
// two comparisons we'll need to build.
|
||||
|
||||
// Canonicalize Cmp1 into the form we expect.
|
||||
// FIXME: we shouldn't care about lanes that are 'undef' in the end?
|
||||
switch (Pred1) {
|
||||
case ICmpInst::Predicate::ICMP_SLT:
|
||||
break;
|
||||
case ICmpInst::Predicate::ICMP_SLE:
|
||||
// We'd have to increment C2 by one, and for that it must not have signed
|
||||
// max element, but then it would have been canonicalized to 'slt' before
|
||||
// we get here. So we can't do anything useful with 'sle'.
|
||||
return nullptr;
|
||||
case ICmpInst::Predicate::ICMP_SGT:
|
||||
// We want to canonicalize it to 'slt', so we'll need to increment C2,
|
||||
// which again means it must not have any signed max elements.
|
||||
if (!match(C2,
|
||||
m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE,
|
||||
APInt::getSignedMaxValue(
|
||||
C2->getType()->getScalarSizeInBits()))))
|
||||
return nullptr; // Can't do, have signed max element[s].
|
||||
C2 = AddOne(C2);
|
||||
LLVM_FALLTHROUGH;
|
||||
case ICmpInst::Predicate::ICMP_SGE:
|
||||
// Also non-canonical, but here we don't need to change C2,
|
||||
// so we don't have any restrictions on C2, so we can just handle it.
|
||||
std::swap(ReplacementLow, ReplacementHigh);
|
||||
break;
|
||||
default:
|
||||
return nullptr; // Unknown predicate.
|
||||
}
|
||||
|
||||
// The thresholds of this clamp-like pattern.
|
||||
auto *ThresholdLowIncl = ConstantExpr::getNeg(C1);
|
||||
auto *ThresholdHighExcl = ConstantExpr::getSub(C0, C1);
|
||||
|
||||
// The fold has a precondition 1: C2 s>= ThresholdLow
|
||||
auto *Precond1 = ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_SGE, C2,
|
||||
ThresholdLowIncl);
|
||||
if (!match(Precond1, m_One()))
|
||||
return nullptr;
|
||||
// The fold has a precondition 2: C2 s<= ThresholdHigh
|
||||
auto *Precond2 = ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_SLE, C2,
|
||||
ThresholdHighExcl);
|
||||
if (!match(Precond2, m_One()))
|
||||
return nullptr;
|
||||
|
||||
// All good, finally emit the new pattern.
|
||||
Value *ShouldReplaceLow = Builder.CreateICmpSLT(X, ThresholdLowIncl);
|
||||
Value *ShouldReplaceHigh = Builder.CreateICmpSGE(X, ThresholdHighExcl);
|
||||
Value *MaybeReplacedLow =
|
||||
Builder.CreateSelect(ShouldReplaceLow, ReplacementLow, X);
|
||||
Instruction *MaybeReplacedHigh =
|
||||
SelectInst::Create(ShouldReplaceHigh, ReplacementHigh, MaybeReplacedLow);
|
||||
|
||||
return MaybeReplacedHigh;
|
||||
}
|
||||
|
||||
/// Visit a SelectInst that has an ICmpInst as its first operand.
|
||||
Instruction *InstCombiner::foldSelectInstWithICmp(SelectInst &SI,
|
||||
ICmpInst *ICI) {
|
||||
@ -1130,6 +1273,9 @@ Instruction *InstCombiner::foldSelectInstWithICmp(SelectInst &SI,
|
||||
if (Instruction *NewAbs = canonicalizeAbsNabs(SI, *ICI, Builder))
|
||||
return NewAbs;
|
||||
|
||||
if (Instruction *NewAbs = canonicalizeClampLike(SI, *ICI, Builder))
|
||||
return NewAbs;
|
||||
|
||||
bool Changed = adjustMinMax(SI, *ICI);
|
||||
|
||||
if (Value *V = foldSelectICmpAnd(SI, ICI, Builder))
|
||||
|
@ -25,11 +25,10 @@
|
||||
|
||||
define i32 @t0_ult_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t0_ult_slt_128(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 128
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 128
|
||||
@ -41,11 +40,10 @@ define i32 @t0_ult_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
}
|
||||
define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t1_ult_slt_0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, -16
|
||||
@ -58,11 +56,10 @@ define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define i32 @t2_ult_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t2_ult_sgt_128(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 127
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, 127
|
||||
@ -74,11 +71,10 @@ define i32 @t2_ult_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
}
|
||||
define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t3_ult_sgt_neg1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -17
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, -17
|
||||
@ -91,11 +87,10 @@ define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
|
||||
define i32 @t4_ugt_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t4_ugt_slt_128(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 128
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ugt i32 [[T2]], 143
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 128
|
||||
@ -107,11 +102,10 @@ define i32 @t4_ugt_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
}
|
||||
define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t5_ugt_slt_0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ugt i32 [[T2]], 143
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, -16
|
||||
@ -124,11 +118,10 @@ define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define i32 @t6_ugt_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t6_ugt_sgt_128(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 127
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ugt i32 [[T2]], 143
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, 127
|
||||
@ -140,11 +133,10 @@ define i32 @t6_ugt_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
}
|
||||
define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t7_ugt_sgt_neg1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -17
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ugt i32 [[T2]], 143
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, -17
|
||||
@ -205,10 +197,10 @@ define i32 @t10_oneuse0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t10_oneuse0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
|
||||
; CHECK-NEXT: call void @use1(i1 [[T0]])
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 64
|
||||
@ -241,12 +233,12 @@ define i32 @n11_oneuse1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; This one is ok.
|
||||
define i32 @t12_oneuse2(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t12_oneuse2(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16
|
||||
; CHECK-NEXT: [[T2:%.*]] = add i32 [[X:%.*]], 16
|
||||
; CHECK-NEXT: call void @use32(i32 [[T2]])
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 128
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 64
|
||||
@ -414,11 +406,10 @@ define i32 @n19_oneuse9(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define <2 x i32> @t20_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t20_ult_slt_vec_splat(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 128>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 144>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 128, i32 128>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[TMP3]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <2 x i32> %x, <i32 128, i32 128>
|
||||
@ -430,11 +421,10 @@ define <2 x i32> @t20_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low
|
||||
}
|
||||
define <2 x i32> @t21_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t21_ult_slt_vec_nonsplat(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 64>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 8>
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 264>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -8>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 128, i32 256>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[TMP3]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <2 x i32> %x, <i32 128, i32 64>
|
||||
@ -473,10 +463,10 @@ define <2 x i32> @t23_ult_sge(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32
|
||||
; CHECK-LABEL: @t23_ult_sge(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sge <2 x i32> [[X:%.*]], <i32 128, i32 -2147483648>
|
||||
; CHECK-NEXT: call void @use2xi1(<2 x i1> [[T0]])
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 -2147483648>
|
||||
; CHECK-NEXT: [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 -1>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X]], <i32 -16, i32 -2147483648>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 128, i32 2147483647>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[TMP3]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp sge <2 x i32> %x, <i32 128, i32 -2147483648>
|
||||
|
@ -25,10 +25,10 @@
|
||||
|
||||
define i32 @t0_ult_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t0_ult_slt_65536(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 65536
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 65536
|
||||
@ -39,10 +39,10 @@ define i32 @t0_ult_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high
|
||||
}
|
||||
define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t1_ult_slt_0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 0
|
||||
@ -54,10 +54,10 @@ define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define i32 @t2_ult_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t2_ult_sgt_65536(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 65535
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, 65535
|
||||
@ -68,10 +68,10 @@ define i32 @t2_ult_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high
|
||||
}
|
||||
define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t3_ult_sgt_neg1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, -1
|
||||
@ -83,10 +83,10 @@ define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high)
|
||||
|
||||
define i32 @t4_ugt_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t4_ugt_slt_65536(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 65536
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ugt i32 [[X]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 65536
|
||||
@ -97,10 +97,10 @@ define i32 @t4_ugt_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high
|
||||
}
|
||||
define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t5_ugt_slt_0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ugt i32 [[X]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32 %x, 0
|
||||
@ -112,10 +112,10 @@ define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define i32 @t6_ugt_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t6_ugt_sgt_65536(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 65535
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ugt i32 [[X]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, 65535
|
||||
@ -126,10 +126,10 @@ define i32 @t6_ugt_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high
|
||||
}
|
||||
define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
; CHECK-LABEL: @t7_ugt_sgt_neg1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ugt i32 [[X]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], 65536
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%t0 = icmp sgt i32 %x, -1
|
||||
@ -311,10 +311,10 @@ define i32 @n16_oneuse6(i32 %x, i32 %replacement_low, i32 %replacement_high) {
|
||||
|
||||
define <2 x i32> @t17_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t17_ult_slt_vec_splat(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65536, i32 65536>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult <2 x i32> [[X]], <i32 65536, i32 65536>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[X]], <2 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 65536, i32 65536>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[TMP3]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <2 x i32> %x, <i32 65536, i32 65536>
|
||||
@ -325,10 +325,10 @@ define <2 x i32> @t17_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low
|
||||
}
|
||||
define <2 x i32> @t18_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t18_ult_slt_vec_nonsplat(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65536, i32 32768>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult <2 x i32> [[X]], <i32 65536, i32 32768>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[X]], <2 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[X]], <i32 65536, i32 32768>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[TMP3]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <2 x i32> %x, <i32 65536, i32 32768>
|
||||
@ -340,10 +340,10 @@ define <2 x i32> @t18_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_
|
||||
|
||||
define <3 x i32> @t19_ult_slt_vec_undef0(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t19_ult_slt_vec_undef0(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <3 x i32> [[X:%.*]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <3 x i1> [[T0]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult <3 x i32> [[X]], <i32 65536, i32 65536, i32 65536>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[T2]], <3 x i32> [[X]], <3 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <3 x i32> [[X]], <i32 65536, i32 65536, i32 65536>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[TMP3]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <3 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
|
||||
@ -354,10 +354,10 @@ define <3 x i32> @t19_ult_slt_vec_undef0(<3 x i32> %x, <3 x i32> %replacement_lo
|
||||
}
|
||||
define <3 x i32> @t20_ult_slt_vec_undef1(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t20_ult_slt_vec_undef1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <3 x i32> [[X:%.*]], <i32 65536, i32 65537, i32 65536>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <3 x i1> [[T0]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult <3 x i32> [[X]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[T2]], <3 x i32> [[X]], <3 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <3 x i32> [[X]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[TMP3]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <3 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <3 x i32> %x, <i32 65536, i32 65537, i32 65536>
|
||||
@ -368,10 +368,10 @@ define <3 x i32> @t20_ult_slt_vec_undef1(<3 x i32> %x, <3 x i32> %replacement_lo
|
||||
}
|
||||
define <3 x i32> @t21_ult_slt_vec_undef2(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
|
||||
; CHECK-LABEL: @t21_ult_slt_vec_undef2(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt <3 x i32> [[X:%.*]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[T1:%.*]] = select <3 x i1> [[T0]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult <3 x i32> [[X]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[T2]], <3 x i32> [[X]], <3 x i32> [[T1]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <3 x i32> [[X]], <i32 65536, i32 undef, i32 65536>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[TMP3]], <3 x i32> [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: ret <3 x i32> [[R]]
|
||||
;
|
||||
%t0 = icmp slt <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
|
||||
@ -380,3 +380,20 @@ define <3 x i32> @t21_ult_slt_vec_undef2(<3 x i32> %x, <3 x i32> %replacement_lo
|
||||
%r = select <3 x i1> %t2, <3 x i32> %x, <3 x i32> %t1
|
||||
ret <3 x i32> %r
|
||||
}
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
define i32* @t22_pointers(i32* %x, i32* %replacement_low, i32* %replacement_high) {
|
||||
; CHECK-LABEL: @t22_pointers(
|
||||
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32* [[X:%.*]], inttoptr (i64 65536 to i32*)
|
||||
; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32* [[REPLACEMENT_LOW:%.*]], i32* [[REPLACEMENT_HIGH:%.*]]
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp ult i32* [[X]], inttoptr (i64 65536 to i32*)
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[T2]], i32* [[X]], i32* [[T1]]
|
||||
; CHECK-NEXT: ret i32* [[R]]
|
||||
;
|
||||
%t0 = icmp slt i32* %x, inttoptr (i64 65536 to i32*)
|
||||
%t1 = select i1 %t0, i32* %replacement_low, i32* %replacement_high
|
||||
%t2 = icmp ult i32* %x, inttoptr (i64 65536 to i32*)
|
||||
%r = select i1 %t2, i32* %x, i32* %t1
|
||||
ret i32* %r
|
||||
}
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
define i32 @t0_select_cond_and_v0(i32 %X) {
|
||||
; CHECK-LABEL: @t0_select_cond_and_v0(
|
||||
; CHECK-NEXT: [[DONT_NEED_TO_CLAMP_POSITIVE:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[DONT_NEED_TO_CLAMP_POSITIVE]], i32 -32768, i32 32767
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32768
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%dont_need_to_clamp_positive = icmp sle i32 %X, 32767
|
||||
@ -23,11 +22,10 @@ define i32 @t0_select_cond_and_v0(i32 %X) {
|
||||
}
|
||||
define i32 @t1_select_cond_and_v1(i32 %X) {
|
||||
; CHECK-LABEL: @t1_select_cond_and_v1(
|
||||
; CHECK-NEXT: [[DONT_NEED_TO_CLAMP_NEGATIVE:%.*]] = icmp sgt i32 [[X:%.*]], -32769
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[DONT_NEED_TO_CLAMP_NEGATIVE]], i32 32767, i32 -32768
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32768
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65536
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%dont_need_to_clamp_positive = icmp sle i32 %X, 32767
|
||||
@ -42,11 +40,10 @@ define i32 @t1_select_cond_and_v1(i32 %X) {
|
||||
|
||||
define i32 @t2_select_cond_or_v0(i32 %X) {
|
||||
; CHECK-LABEL: @t2_select_cond_or_v0(
|
||||
; CHECK-NEXT: [[NEED_TO_CLAMP_POSITIVE:%.*]] = icmp sgt i32 [[X:%.*]], 32767
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[NEED_TO_CLAMP_POSITIVE]], i32 32767, i32 -32768
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32768
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[CLAMP_LIMIT]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%need_to_clamp_positive = icmp sgt i32 %X, 32767
|
||||
@ -58,11 +55,10 @@ define i32 @t2_select_cond_or_v0(i32 %X) {
|
||||
}
|
||||
define i32 @t3_select_cond_or_v1(i32 %X) {
|
||||
; CHECK-LABEL: @t3_select_cond_or_v1(
|
||||
; CHECK-NEXT: [[NEED_TO_CLAMP_NEGATIVE:%.*]] = icmp slt i32 [[X:%.*]], -32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[NEED_TO_CLAMP_NEGATIVE]], i32 -32768, i32 32767
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32768
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[CLAMP_LIMIT]], i32 [[X]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%need_to_clamp_positive = icmp sgt i32 %X, 32767
|
||||
@ -77,11 +73,10 @@ define i32 @t3_select_cond_or_v1(i32 %X) {
|
||||
|
||||
define i32 @t4_select_cond_xor_v0(i32 %X) {
|
||||
; CHECK-LABEL: @t4_select_cond_xor_v0(
|
||||
; CHECK-NEXT: [[NEED_TO_CLAMP_POSITIVE:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[NEED_TO_CLAMP_POSITIVE]], i32 -32768, i32 32767
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32767
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%need_to_clamp_positive = icmp sgt i32 %X, 32767
|
||||
@ -93,11 +88,10 @@ define i32 @t4_select_cond_xor_v0(i32 %X) {
|
||||
}
|
||||
define i32 @t4_select_cond_xor_v1(i32 %X) {
|
||||
; CHECK-LABEL: @t4_select_cond_xor_v1(
|
||||
; CHECK-NEXT: [[DONT_NEED_TO_CLAMP_NEGATIVE:%.*]] = icmp sgt i32 [[X:%.*]], -32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[DONT_NEED_TO_CLAMP_NEGATIVE]], i32 32767, i32 -32768
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32767
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%need_to_clamp_positive = icmp sgt i32 %X, 32767
|
||||
@ -110,11 +104,10 @@ define i32 @t4_select_cond_xor_v1(i32 %X) {
|
||||
|
||||
define i32 @t5_select_cond_xor_v2(i32 %X) {
|
||||
; CHECK-LABEL: @t5_select_cond_xor_v2(
|
||||
; CHECK-NEXT: [[NEED_TO_CLAMP_NEGATIVE:%.*]] = icmp sgt i32 [[X:%.*]], -32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[NEED_TO_CLAMP_NEGATIVE]], i32 32767, i32 -32768
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32767
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%dont_need_to_clamp_positive = icmp sle i32 %X, 32767
|
||||
@ -126,11 +119,10 @@ define i32 @t5_select_cond_xor_v2(i32 %X) {
|
||||
}
|
||||
define i32 @t5_select_cond_xor_v3(i32 %X) {
|
||||
; CHECK-LABEL: @t5_select_cond_xor_v3(
|
||||
; CHECK-NEXT: [[DONT_NEED_TO_CLAMP_POSITIVE:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[CLAMP_LIMIT:%.*]] = select i1 [[DONT_NEED_TO_CLAMP_POSITIVE]], i32 -32768, i32 32767
|
||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], 32767
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 65535
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[CLAMP_LIMIT]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 32768
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -32768
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[X]], i32 -32768
|
||||
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 32767
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
%dont_need_to_clamp_positive = icmp sle i32 %X, 32767
|
||||
|
Loading…
Reference in New Issue
Block a user