mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[InstCombine] Fold comparison of integers by parts
Let's say you represent (i32, i32) as an i64 from which the parts are extracted with lshr/trunc. Then, if you compare two tuples by parts you get something like A[0] == B[0] && A[1] == B[1], just that the part extraction happens by lshr/trunc and not a narrow load or similar. The fold implemented here reduces such equality comparisons by converting them into a comparison on a larger part of the integer (which might be the whole integer). It handles both the "and of eq" and the conjugated "or of ne" case. I'm being conservative with one-use for now, though this could be relaxed if profitable (the base pattern converts 11 instructions into 5 instructions, but there's quite a few variations on how it can play out). Differential Revision: https://reviews.llvm.org/D101232
This commit is contained in:
parent
2fe8d357e6
commit
b75831fe6a
@ -1076,6 +1076,87 @@ static Value *foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct IntPart {
|
||||
Value *From;
|
||||
unsigned StartBit;
|
||||
unsigned NumBits;
|
||||
};
|
||||
|
||||
/// Match an extraction of bits from an integer.
|
||||
static Optional<IntPart> matchIntPart(Value *V) {
|
||||
Value *X;
|
||||
if (!match(V, m_OneUse(m_Trunc(m_Value(X)))))
|
||||
return None;
|
||||
|
||||
unsigned NumOriginalBits = X->getType()->getScalarSizeInBits();
|
||||
unsigned NumExtractedBits = V->getType()->getScalarSizeInBits();
|
||||
Value *Y;
|
||||
const APInt *Shift;
|
||||
// For a trunc(lshr Y, Shift) pattern, make sure we're only extracting bits
|
||||
// from Y, not any shifted-in zeroes.
|
||||
if (match(X, m_OneUse(m_LShr(m_Value(Y), m_APInt(Shift)))) &&
|
||||
Shift->ule(NumOriginalBits - NumExtractedBits))
|
||||
return {{Y, (unsigned)Shift->getZExtValue(), NumExtractedBits}};
|
||||
return {{X, 0, NumExtractedBits}};
|
||||
}
|
||||
|
||||
/// Materialize an extraction of bits from an integer in IR.
|
||||
static Value *extractIntPart(const IntPart &P, IRBuilderBase &Builder) {
|
||||
Value *V = P.From;
|
||||
if (P.StartBit)
|
||||
V = Builder.CreateLShr(V, P.StartBit);
|
||||
Type *TruncTy = V->getType()->getWithNewBitWidth(P.NumBits);
|
||||
if (TruncTy != V->getType())
|
||||
V = Builder.CreateTrunc(V, TruncTy);
|
||||
return V;
|
||||
}
|
||||
|
||||
/// (icmp eq X0, Y0) & (icmp eq X1, Y1) -> icmp eq X01, Y01
|
||||
/// (icmp ne X0, Y0) | (icmp ne X1, Y1) -> icmp ne X01, Y01
|
||||
/// where X0, X1 and Y0, Y1 are adjacent parts extracted from an integer.
|
||||
static Value *foldEqOfParts(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd,
|
||||
InstCombiner::BuilderTy &Builder) {
|
||||
if (!Cmp0->hasOneUse() || !Cmp1->hasOneUse())
|
||||
return nullptr;
|
||||
|
||||
CmpInst::Predicate Pred = IsAnd ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE;
|
||||
if (Cmp0->getPredicate() != Pred || Cmp1->getPredicate() != Pred)
|
||||
return nullptr;
|
||||
|
||||
Optional<IntPart> L0 = matchIntPart(Cmp0->getOperand(0));
|
||||
Optional<IntPart> R0 = matchIntPart(Cmp0->getOperand(1));
|
||||
Optional<IntPart> L1 = matchIntPart(Cmp1->getOperand(0));
|
||||
Optional<IntPart> R1 = matchIntPart(Cmp1->getOperand(1));
|
||||
if (!L0 || !R0 || !L1 || !R1)
|
||||
return nullptr;
|
||||
|
||||
// Make sure the LHS/RHS compare a part of the same value, possibly after
|
||||
// an operand swap.
|
||||
if (L0->From != L1->From || R0->From != R1->From) {
|
||||
if (L0->From != R1->From || R0->From != L1->From)
|
||||
return nullptr;
|
||||
std::swap(L1, R1);
|
||||
}
|
||||
|
||||
// Make sure the extracted parts are adjacent, canonicalizing to L0/R0 being
|
||||
// the low part and L1/R1 being the high part.
|
||||
if (L0->StartBit + L0->NumBits != L1->StartBit ||
|
||||
R0->StartBit + R0->NumBits != R1->StartBit) {
|
||||
if (L1->StartBit + L1->NumBits != L0->StartBit ||
|
||||
R1->StartBit + R1->NumBits != R0->StartBit)
|
||||
return nullptr;
|
||||
std::swap(L0, L1);
|
||||
std::swap(R0, R1);
|
||||
}
|
||||
|
||||
// We can simplify to a comparison of these larger parts of the integers.
|
||||
IntPart L = {L0->From, L0->StartBit, L0->NumBits + L1->NumBits};
|
||||
IntPart R = {R0->From, R0->StartBit, R0->NumBits + R1->NumBits};
|
||||
Value *LValue = extractIntPart(L, Builder);
|
||||
Value *RValue = extractIntPart(R, Builder);
|
||||
return Builder.CreateICmp(Pred, LValue, RValue);
|
||||
}
|
||||
|
||||
/// Reduce logic-of-compares with equality to a constant by substituting a
|
||||
/// common operand with the constant. Callers are expected to call this with
|
||||
/// Cmp0/Cmp1 switched to handle logic op commutativity.
|
||||
@ -1181,6 +1262,9 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
|
||||
foldUnsignedUnderflowCheck(RHS, LHS, /*IsAnd=*/true, Q, Builder))
|
||||
return X;
|
||||
|
||||
if (Value *X = foldEqOfParts(LHS, RHS, /*IsAnd=*/true, Builder))
|
||||
return X;
|
||||
|
||||
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
|
||||
Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
|
||||
|
||||
@ -2411,6 +2495,9 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
|
||||
foldUnsignedUnderflowCheck(RHS, LHS, /*IsAnd=*/false, Q, Builder))
|
||||
return X;
|
||||
|
||||
if (Value *X = foldEqOfParts(LHS, RHS, /*IsAnd=*/false, Builder))
|
||||
return X;
|
||||
|
||||
// (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
|
||||
// TODO: Remove this when foldLogOpOfMaskedICmps can handle vectors.
|
||||
if (PredL == ICmpInst::ICMP_NE && match(LHS1, m_Zero()) &&
|
||||
|
@ -10,16 +10,10 @@ declare void @use.i1(i1)
|
||||
|
||||
define i1 @eq_10(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_10(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp eq i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = and i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_10]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i16 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i1 [[TMP3]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -35,22 +29,10 @@ define i1 @eq_10(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_210(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_210(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp eq i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = and i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_10]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i24 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i1 [[TMP3]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -72,28 +54,8 @@ define i1 @eq_210(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_3210(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_3210(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[X_3_EXT:%.*]] = lshr i32 [[X]], 24
|
||||
; CHECK-NEXT: [[X_3:%.*]] = trunc i32 [[X_3_EXT]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[Y_3_EXT:%.*]] = lshr i32 [[Y]], 24
|
||||
; CHECK-NEXT: [[Y_3:%.*]] = trunc i32 [[Y_3_EXT]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp eq i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i8 [[X_3]], [[Y_3]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = and i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_10]]
|
||||
; CHECK-NEXT: [[C_3210:%.*]] = and i1 [[C_3]], [[C_210]]
|
||||
; CHECK-NEXT: ret i1 [[C_3210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i1 [[TMP1]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -121,18 +83,12 @@ define i1 @eq_3210(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_21(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_21(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -152,18 +108,12 @@ define i1 @eq_21(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_21_comm_and(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_21_comm_and(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -181,18 +131,12 @@ define i1 @eq_21_comm_and(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_21_comm_eq(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_21_comm_eq(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[Y_2]], [[X_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -210,18 +154,12 @@ define i1 @eq_21_comm_eq(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @eq_21_comm_eq2(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @eq_21_comm_eq2(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[Y_1]], [[X_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -241,18 +179,12 @@ define i1 @eq_21_comm_eq2(i32 %x, i32 %y) {
|
||||
|
||||
define <2x i1> @eq_21_vector(<2x i32> %x, <2x i32> %y) {
|
||||
; CHECK-LABEL: @eq_21_vector(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc <2 x i32> [[X_321]] to <2 x i8>
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr <2 x i32> [[X]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc <2 x i32> [[X_32]] to <2 x i8>
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc <2 x i32> [[Y_321]] to <2 x i8>
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr <2 x i32> [[Y]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc <2 x i32> [[Y_32]] to <2 x i8>
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq <2 x i8> [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq <2 x i8> [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and <2 x i1> [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <2 x i16> [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr <2x i32> %x, <i32 8, i32 8>
|
||||
%x.1 = trunc <2x i32> %x.321 to <2x i8>
|
||||
@ -273,18 +205,12 @@ define <2x i1> @eq_21_vector(<2x i32> %x, <2x i32> %y) {
|
||||
|
||||
define i1 @eq_irregular_bit_widths(i31 %x, i31 %y) {
|
||||
; CHECK-LABEL: @eq_irregular_bit_widths(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i31 [[X:%.*]], 7
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i31 [[X_321]] to i6
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i31 [[X]], 13
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i31 [[X_32]] to i5
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i31 [[Y:%.*]], 7
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i31 [[Y_321]] to i6
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i31 [[Y]], 13
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i31 [[Y_32]] to i5
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i6 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i5 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i11 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i31 %x, 7
|
||||
%x.1 = trunc i31 %x.321 to i6
|
||||
@ -724,16 +650,10 @@ define i1 @eq_21_wrong_pred2(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_10(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_10(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp ne i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = or i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_10]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i16 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i1 [[TMP3]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -749,22 +669,10 @@ define i1 @ne_10(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_210(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_210(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp ne i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = or i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_10]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i24 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: ret i1 [[TMP3]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -786,28 +694,8 @@ define i1 @ne_210(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_3210(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_3210(
|
||||
; CHECK-NEXT: [[X_0:%.*]] = trunc i32 [[X:%.*]] to i8
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[X_3_EXT:%.*]] = lshr i32 [[X]], 24
|
||||
; CHECK-NEXT: [[X_3:%.*]] = trunc i32 [[X_3_EXT]] to i8
|
||||
; CHECK-NEXT: [[Y_0:%.*]] = trunc i32 [[Y:%.*]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[Y_3_EXT:%.*]] = lshr i32 [[Y]], 24
|
||||
; CHECK-NEXT: [[Y_3:%.*]] = trunc i32 [[Y_3_EXT]] to i8
|
||||
; CHECK-NEXT: [[C_0:%.*]] = icmp ne i8 [[X_0]], [[Y_0]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp ne i8 [[X_3]], [[Y_3]]
|
||||
; CHECK-NEXT: [[C_10:%.*]] = or i1 [[C_0]], [[C_1]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_10]]
|
||||
; CHECK-NEXT: [[C_3210:%.*]] = or i1 [[C_3]], [[C_210]]
|
||||
; CHECK-NEXT: ret i1 [[C_3210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i1 [[TMP1]]
|
||||
;
|
||||
%x.0 = trunc i32 %x to i8
|
||||
%x.321 = lshr i32 %x, 8
|
||||
@ -835,18 +723,12 @@ define i1 @ne_3210(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_21(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_21(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -866,18 +748,12 @@ define i1 @ne_21(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_21_comm_or(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_21_comm_or(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -895,18 +771,12 @@ define i1 @ne_21_comm_or(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_21_comm_ne(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_21_comm_ne(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[Y_2]], [[X_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -924,18 +794,12 @@ define i1 @ne_21_comm_ne(i32 %x, i32 %y) {
|
||||
|
||||
define i1 @ne_21_comm_ne2(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @ne_21_comm_ne2(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[Y_1]], [[X_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i32 %x, 8
|
||||
%x.1 = trunc i32 %x.321 to i8
|
||||
@ -955,18 +819,12 @@ define i1 @ne_21_comm_ne2(i32 %x, i32 %y) {
|
||||
|
||||
define <2x i1> @ne_21_vector(<2x i32> %x, <2x i32> %y) {
|
||||
; CHECK-LABEL: @ne_21_vector(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc <2 x i32> [[X_321]] to <2 x i8>
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr <2 x i32> [[X]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc <2 x i32> [[X_32]] to <2 x i8>
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc <2 x i32> [[Y_321]] to <2 x i8>
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr <2 x i32> [[Y]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc <2 x i32> [[Y_32]] to <2 x i8>
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne <2 x i8> [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne <2 x i8> [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or <2 x i1> [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <2 x i16> [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr <2x i32> %x, <i32 8, i32 8>
|
||||
%x.1 = trunc <2x i32> %x.321 to <2x i8>
|
||||
@ -987,18 +845,12 @@ define <2x i1> @ne_21_vector(<2x i32> %x, <2x i32> %y) {
|
||||
|
||||
define i1 @ne_irregular_bit_widths(i31 %x, i31 %y) {
|
||||
; CHECK-LABEL: @ne_irregular_bit_widths(
|
||||
; CHECK-NEXT: [[X_321:%.*]] = lshr i31 [[X:%.*]], 7
|
||||
; CHECK-NEXT: [[X_1:%.*]] = trunc i31 [[X_321]] to i6
|
||||
; CHECK-NEXT: [[X_32:%.*]] = lshr i31 [[X]], 13
|
||||
; CHECK-NEXT: [[X_2:%.*]] = trunc i31 [[X_32]] to i5
|
||||
; CHECK-NEXT: [[Y_321:%.*]] = lshr i31 [[Y:%.*]], 7
|
||||
; CHECK-NEXT: [[Y_1:%.*]] = trunc i31 [[Y_321]] to i6
|
||||
; CHECK-NEXT: [[Y_32:%.*]] = lshr i31 [[Y]], 13
|
||||
; CHECK-NEXT: [[Y_2:%.*]] = trunc i31 [[Y_32]] to i5
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i6 [[X_1]], [[Y_1]]
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i5 [[X_2]], [[Y_2]]
|
||||
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[C_210]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i11 [[TMP2]], [[TMP4]]
|
||||
; CHECK-NEXT: ret i1 [[TMP5]]
|
||||
;
|
||||
%x.321 = lshr i31 %x, 7
|
||||
%x.1 = trunc i31 %x.321 to i6
|
||||
|
Loading…
Reference in New Issue
Block a user