]> granicus.if.org Git - llvm/commitdiff
[ConstantFolder] Don't try to fold gep when the idx is a vector.
authorDavide Italiano <davide@freebsd.org>
Thu, 27 Jul 2017 22:20:44 +0000 (22:20 +0000)
committerDavide Italiano <davide@freebsd.org>
Thu, 27 Jul 2017 22:20:44 +0000 (22:20 +0000)
The code in ConstantFoldGetElementPtr() assumes integers, and
therefore it crashes trying to get the integer bidwith of a vector
type (in this case <4 x i32>. I just changed the code to prevent
the folding in case of vectors and I didn't bother to generalize
as this doesn't seem to me something that really happens in
practice, but I'm willing to change the patch if you think
it's worth it.
This is hard to trigger from -instsimplify or -instcombine
only as the second instruction is dead, so the test uses loop-unroll.

Differential Revision:  https://reviews.llvm.org/D35956

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309330 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/ConstantFold.cpp
test/Transforms/InstSimplify/pr33957.ll [new file with mode: 0644]

index 23ccd8d4cf424ca642c23ec63f4fdd96d89e2daa..311b0a76ce8ab507e6ee10c587825d0ebb9c3719 100644 (file)
@@ -2097,15 +2097,19 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
       // Subsequent evaluation would get confused and produce erroneous results.
       //
       // The following prohibits such a GEP from being formed by checking to see
-      // if the index is in-range with respect to an array or vector.
+      // if the index is in-range with respect to an array.
+      // TODO: This code may be extended to handle vectors as well.
       bool PerformFold = false;
       if (Idx0->isNullValue())
         PerformFold = true;
       else if (LastI.isSequential())
         if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0))
-          PerformFold =
-              !LastI.isBoundedSequential() ||
-              isIndexInRangeOfArrayType(LastI.getSequentialNumElements(), CI);
+          PerformFold = (!LastI.isBoundedSequential() ||
+                         isIndexInRangeOfArrayType(
+                             LastI.getSequentialNumElements(), CI)) &&
+                        !CE->getOperand(CE->getNumOperands() - 1)
+                             ->getType()
+                             ->isVectorTy();
 
       if (PerformFold) {
         SmallVector<Value*, 16> NewIndices;
diff --git a/test/Transforms/InstSimplify/pr33957.ll b/test/Transforms/InstSimplify/pr33957.ll
new file mode 100644 (file)
index 0000000..256bb89
--- /dev/null
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -loop-unroll -S %s | FileCheck %s
+
+%struct.bar = type { i32 }
+
+@global = external constant [78 x %struct.bar], align 4
+
+define void @patatino(i32 %x) {
+; CHECK-LABEL: @patatino(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    br i1 true, label [[BB1_PREHEADER:%.*]], label [[BB3:%.*]]
+; CHECK:       bb1.preheader:
+; CHECK-NEXT:    br label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret void
+;
+bb:
+  br i1 true, label %bb1, label %bb3
+
+bb1:
+  %tmp = getelementptr inbounds [78 x %struct.bar], [78 x %struct.bar]* @global, i32 0, <4 x i32> undef
+  %tmp2 = getelementptr inbounds %struct.bar, <4 x %struct.bar*> %tmp, i32 1
+  br i1 true, label %bb3, label %bb1
+
+bb3:
+  ret void
+}