From 961f725e69f69e3763c71c20da54cd36dc2eefe4 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Thu, 27 Jul 2017 22:20:44 +0000 Subject: [PATCH] [ConstantFolder] Don't try to fold gep when the idx is a vector. 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 | 12 ++++++---- test/Transforms/InstSimplify/pr33957.ll | 29 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 test/Transforms/InstSimplify/pr33957.ll diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 23ccd8d4cf4..311b0a76ce8 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -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(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 NewIndices; diff --git a/test/Transforms/InstSimplify/pr33957.ll b/test/Transforms/InstSimplify/pr33957.ll new file mode 100644 index 00000000000..256bb89e786 --- /dev/null +++ b/test/Transforms/InstSimplify/pr33957.ll @@ -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 +} -- 2.50.1