[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