[PATCH] D57871: Fix some cases where icmp (bitcast ([su]itofp X)), Y is misfolded
Andrew Scheidecker via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 6 18:19:08 PST 2019
AndrewScheidecker created this revision.
AndrewScheidecker added reviewers: spatel, lebedev.ri.
Herald added a project: LLVM.
This fixes a class of bugs introduced by https://reviews.llvm.org/D44367, which transforms various cases of `icmp (bitcast ([su]itofp X)), Y` to `icmp X, Y`. If the bitcast is between vector types with a different number of elements, the current code will produce bad IR along the lines of: `icmp <N x i32> ..., <M x i32> <...>`.
This patch suppresses the transform if the bitcast changes the number of vector elements.
Repository:
rL LLVM
https://reviews.llvm.org/D57871
Files:
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/cast-int-icmp-eq-0.ll
Index: test/Transforms/InstCombine/cast-int-icmp-eq-0.ll
===================================================================
--- test/Transforms/InstCombine/cast-int-icmp-eq-0.ll
+++ test/Transforms/InstCombine/cast-int-icmp-eq-0.ll
@@ -651,3 +651,34 @@
ret <3 x i1> %cmp
}
+; Verify that the various forms of this transform are not applied when the
+; bitcast changes the number of vector elements:
+; icmp (bitcast ([su]itofp X)), Y -> icmp X, Y
+
+define <6 x i1> @i16_cast_cmp_sgt_int_m1_bitcast_vector_num_elements_sitofp(<3 x i16> %i) {
+; CHECK-LABEL: @i16_cast_cmp_sgt_int_m1_bitcast_vector_num_elements_sitofp(
+; CHECK-NEXT: [[SITOFP:%.*]] = sitofp <3 x i16> [[I:%.*]] to <3 x float>
+; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[SITOFP]] to <6 x i16>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <6 x i16> [[BITCAST]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+; CHECK-NEXT: ret <6 x i1> [[CMP]]
+;
+ %f = sitofp <3 x i16> %i to <3 x float>
+ %b = bitcast <3 x float> %f to <6 x i16>
+ %cmp = icmp sgt <6 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+ ret <6 x i1> %cmp
+}
+
+
+define <6 x i1> @i16_cast_cmp_eq_int_0_bitcast_vector_num_elements_uitofp(<3 x i16> %i) {
+; CHECK-LABEL: @i16_cast_cmp_eq_int_0_bitcast_vector_num_elements_uitofp(
+; CHECK-NEXT: [[UITOFP:%.*]] = uitofp <3 x i16> [[I:%.*]] to <3 x float>
+; CHECK-NEXT: [[BITCAST:%.*]] = bitcast <3 x float> [[UITOFP]] to <6 x i16>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <6 x i16> [[BITCAST]], zeroinitializer
+; CHECK-NEXT: ret <6 x i1> [[CMP]]
+;
+ %f = uitofp <3 x i16> %i to <3 x float>
+ %b = bitcast <3 x float> %f to <6 x i16>
+ %cmp = icmp eq <6 x i16> %b, <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
+ ret <6 x i1> %cmp
+}
+
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4824,6 +4824,11 @@
return nullptr;
}
+static unsigned getVectorNumElementsOrZero(Type *T)
+{
+ return T->isVectorTy() ? T->getVectorNumElements() : 0;
+}
+
Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
bool Changed = false;
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -4947,7 +4952,9 @@
// Zero-equality and sign-bit checks are preserved through sitofp + bitcast.
Value *X;
- if (match(Op0, m_BitCast(m_SIToFP(m_Value(X))))) {
+ if (match(Op0, m_BitCast(m_SIToFP(m_Value(X)))) &&
+ getVectorNumElementsOrZero(X->getType()) ==
+ getVectorNumElementsOrZero(I.getType())) {
// icmp eq (bitcast (sitofp X)), 0 --> icmp eq X, 0
// icmp ne (bitcast (sitofp X)), 0 --> icmp ne X, 0
// icmp slt (bitcast (sitofp X)), 0 --> icmp slt X, 0
@@ -4970,8 +4977,10 @@
// icmp eq (bitcast (uitofp X)), 0 --> icmp eq X, 0
// icmp ne (bitcast (uitofp X)), 0 --> icmp ne X, 0
if (match(Op0, m_BitCast(m_UIToFP(m_Value(X)))))
- if (I.isEquality() && match(Op1, m_Zero()))
- return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
+ if (getVectorNumElementsOrZero(X->getType()) ==
+ getVectorNumElementsOrZero(I.getType()))
+ if (I.isEquality() && match(Op1, m_Zero()))
+ return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
// Test to see if the operands of the icmp are casted versions of other
// values. If the ptr->ptr cast can be stripped off both arguments, we do so
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57871.185687.patch
Type: text/x-patch
Size: 3524 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190207/df886f8d/attachment.bin>
More information about the llvm-commits
mailing list