1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[InstCombine] canonicalize* LE/GE vector integer comparisons to LT/GT (PR26701, PR26819)

*We don't currently handle the  edge case constants (min/max values), so it's not a complete
canonicalization.

To fully solve the motivating bugs, we need to enhance this to recognize a zero vector
too because that's a ConstantAggregateZero which is a ConstantData, not a ConstantVector
or a ConstantDataVector.

Differential Revision: http://reviews.llvm.org/D17859 

llvm-svn: 269426
This commit is contained in:
Sanjay Patel 2016-05-13 15:10:46 +00:00
parent e327d609fa
commit 2c688c8b52
3 changed files with 180 additions and 3 deletions

View File

@ -3125,11 +3125,64 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I,
assert(!Op1C->isMinValue(true)); // A >=s MIN -> TRUE
return new ICmpInst(ICmpInst::ICMP_SGT, Op0, Builder.getInt(Op1Val - 1));
default:
break;
return nullptr;
}
}
// TODO: Handle vectors.
// The usual vector types are ConstantDataVector. Exotic vector types are
// ConstantVector. They both derive from Constant.
if (isa<ConstantDataVector>(Op1) || isa<ConstantVector>(Op1)) {
Constant *Op1C = cast<Constant>(Op1);
Type *Op1Type = Op1->getType();
unsigned NumElts = Op1Type->getVectorNumElements();
// Set the new comparison predicate and splat a vector of 1 or -1 to
// increment or decrement the vector constants. But first, check that no
// elements of the constant vector would overflow/underflow when we
// increment/decrement the constants.
//
// TODO? If the edge cases for vectors were guaranteed to be handled as they
// are for scalar, we could remove the min/max checks here. However, to do
// that, we would have to use insertelement/shufflevector to replace edge
// values.
CmpInst::Predicate NewPred;
Constant *OneOrNegOne = nullptr;
switch (I.getPredicate()) {
case ICmpInst::ICMP_ULE:
for (unsigned i = 0; i != NumElts; ++i)
if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMaxValue(false))
return nullptr;
NewPred = ICmpInst::ICMP_ULT;
OneOrNegOne = ConstantInt::get(Op1Type, 1);
break;
case ICmpInst::ICMP_SLE:
for (unsigned i = 0; i != NumElts; ++i)
if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMaxValue(true))
return nullptr;
NewPred = ICmpInst::ICMP_SLT;
OneOrNegOne = ConstantInt::get(Op1Type, 1);
break;
case ICmpInst::ICMP_UGE:
for (unsigned i = 0; i != NumElts; ++i)
if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMinValue(false))
return nullptr;
NewPred = ICmpInst::ICMP_UGT;
OneOrNegOne = ConstantInt::get(Op1Type, -1);
break;
case ICmpInst::ICMP_SGE:
for (unsigned i = 0; i != NumElts; ++i)
if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMinValue(true))
return nullptr;
NewPred = ICmpInst::ICMP_SGT;
OneOrNegOne = ConstantInt::get(Op1Type, -1);
break;
default:
return nullptr;
}
return new ICmpInst(NewPred, Op0, ConstantExpr::getAdd(Op1C, OneOrNegOne));
}
return nullptr;
}

View File

@ -0,0 +1,124 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
; Canonicalize vector ge/le comparisons with constants to gt/lt.
; Normal types are ConstantDataVectors. Test the constant values adjacent to the
; min/max values that we're not allowed to transform.
define <2 x i1> @sge(<2 x i8> %x) {
; CHECK-LABEL: @sge(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -128, i8 126>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp sge <2 x i8> %x, <i8 -127, i8 -129>
ret <2 x i1> %cmp
}
define <2 x i1> @uge(<2 x i8> %x) {
; CHECK-LABEL: @uge(
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> %x, <i8 -2, i8 0>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp uge <2 x i8> %x, <i8 -1, i8 1>
ret <2 x i1> %cmp
}
define <2 x i1> @sle(<2 x i8> %x) {
; CHECK-LABEL: @sle(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> %x, <i8 127, i8 -127>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp sle <2 x i8> %x, <i8 126, i8 128>
ret <2 x i1> %cmp
}
define <2 x i1> @ule(<2 x i8> %x) {
; CHECK-LABEL: @ule(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> %x, <i8 -1, i8 1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp ule <2 x i8> %x, <i8 254, i8 0>
ret <2 x i1> %cmp
}
; Weird types are ConstantVectors, not ConstantDataVectors. For an i3 type:
; Signed min = -4
; Unsigned min = 0
; Signed max = 3
; Unsigned max = 7
define <3 x i1> @sge_weird(<3 x i3> %x) {
; CHECK-LABEL: @sge_weird(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i3> %x, <i3 -4, i3 2, i3 -1>
; CHECK-NEXT: ret <3 x i1> [[CMP]]
;
%cmp = icmp sge <3 x i3> %x, <i3 -3, i3 -5, i3 0>
ret <3 x i1> %cmp
}
define <3 x i1> @uge_weird(<3 x i3> %x) {
; CHECK-LABEL: @uge_weird(
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <3 x i3> %x, <i3 -2, i3 0, i3 1>
; CHECK-NEXT: ret <3 x i1> [[CMP]]
;
%cmp = icmp uge <3 x i3> %x, <i3 -1, i3 1, i3 2>
ret <3 x i1> %cmp
}
define <3 x i1> @sle_weird(<3 x i3> %x) {
; CHECK-LABEL: @sle_weird(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <3 x i3> %x, <i3 3, i3 -3, i3 1>
; CHECK-NEXT: ret <3 x i1> [[CMP]]
;
%cmp = icmp sle <3 x i3> %x, <i3 2, i3 4, i3 0>
ret <3 x i1> %cmp
}
define <3 x i1> @ule_weird(<3 x i3> %x) {
; CHECK-LABEL: @ule_weird(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <3 x i3> %x, <i3 -1, i3 1, i3 2>
; CHECK-NEXT: ret <3 x i1> [[CMP]]
;
%cmp = icmp ule <3 x i3> %x, <i3 6, i3 0, i3 1>
ret <3 x i1> %cmp
}
; We can't do the transform if any constants are already at the limits.
define <2 x i1> @sge_min(<2 x i3> %x) {
; CHECK-LABEL: @sge_min(
; CHECK-NEXT: [[CMP:%.*]] = icmp sge <2 x i3> %x, <i3 -4, i3 1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp sge <2 x i3> %x, <i3 -4, i3 1>
ret <2 x i1> %cmp
}
define <2 x i1> @uge_min(<2 x i3> %x) {
; CHECK-LABEL: @uge_min(
; CHECK-NEXT: [[CMP:%.*]] = icmp uge <2 x i3> %x, <i3 1, i3 0>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp uge <2 x i3> %x, <i3 1, i3 0>
ret <2 x i1> %cmp
}
define <2 x i1> @sle_max(<2 x i3> %x) {
; CHECK-LABEL: @sle_max(
; CHECK-NEXT: [[CMP:%.*]] = icmp sle <2 x i3> %x, <i3 1, i3 3>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp sle <2 x i3> %x, <i3 1, i3 3>
ret <2 x i1> %cmp
}
define <2 x i1> @ule_max(<2 x i3> %x) {
; CHECK-LABEL: @ule_max(
; CHECK-NEXT: [[CMP:%.*]] = icmp ule <2 x i3> %x, <i3 -1, i3 1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp ule <2 x i3> %x, <i3 7, i3 1>
ret <2 x i1> %cmp
}

View File

@ -73,7 +73,7 @@ for.end:
;CHECK-LABEL: @reduction_func(
;CHECK: load <4 x i32>
;CHECK: add <4 x i32>
;CHECK: icmp sle <4 x i32>
;CHECK: icmp slt <4 x i32>
;CHECK: select <4 x i1>
;CHECK: ret i32
define i32 @reduction_func(i32* nocapture %A, i32 %n) nounwind uwtable readonly ssp {