From: Chandler Carruth Date: Fri, 28 Aug 2015 09:03:52 +0000 (+0000) Subject: [SROA] Fix PR24463, a crash I introduced in SROA by allowing it to X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=9befb59470dddd7f9f684de8c4f48748e861fe32;ds=inline [SROA] Fix PR24463, a crash I introduced in SROA by allowing it to handle more allocas with loads past the end of the alloca. I suspect there are some related crashers with slightly different patterns, but I'll fix those and add test cases as I find them. Thanks to David Majnemer for the excellent test case reduction here. Made this super simple to debug and fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246289 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index d37d1e753eb..cd9f8bfaa68 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2471,9 +2471,19 @@ private: V = convertValue(DL, IRB, V, IntTy); assert(NewBeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset; - if (Offset > 0 || NewEndOffset < NewAllocaEndOffset) - V = extractInteger(DL, IRB, V, cast(LI.getType()), Offset, - "extract"); + if (Offset > 0 || NewEndOffset < NewAllocaEndOffset) { + IntegerType *ExtractTy = Type::getIntNTy(LI.getContext(), SliceSize * 8); + V = extractInteger(DL, IRB, V, ExtractTy, Offset, "extract"); + } + // It is possible that the extracted type is not the load type. This + // happens if there is a load past the end of the alloca, and as + // a consequence the slice is narrower but still a candidate for integer + // lowering. To handle this case, we just zero extend the extracted + // integer. + assert(cast(LI.getType())->getBitWidth() >= SliceSize * 8 && + "Can only handle an extract for an overly wide load"); + if (cast(LI.getType())->getBitWidth() > SliceSize * 8) + V = IRB.CreateZExt(V, LI.getType()); return V; } diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll index 009f16a80bb..25b8e8ba41f 100644 --- a/test/Transforms/SROA/basictest.ll +++ b/test/Transforms/SROA/basictest.ll @@ -1609,3 +1609,26 @@ entry: %load = load atomic volatile i64, i64* %ptr seq_cst, align 8 ret void } + +define i16 @PR24463() { +; Ensure we can handle a very interesting case where there is an integer-based +; rewrite of the uses of the alloca, but where one of the integers in that is +; a sub-integer that requires extraction *and* extends past the end of the +; alloca. In this case, we should extract the i8 and then zext it to i16. +; +; CHECK-LABEL @PR24463( +; CHECK-NOT: alloca +; CHECK: %[[SHIFT:.*]] = lshr i16 0, 8 +; CHECK: %[[TRUNC:.*]] = trunc i16 %[[SHIFT]] to i8 +; CHECK: %[[ZEXT:.*]] = zext i8 %[[TRUNC]] to i16 +; CHECK: ret i16 %[[ZEXT]] +entry: + %alloca = alloca [3 x i8] + %gep1 = getelementptr inbounds [3 x i8], [3 x i8]* %alloca, i64 0, i64 1 + %bc1 = bitcast i8* %gep1 to i16* + store i16 0, i16* %bc1 + %gep2 = getelementptr inbounds [3 x i8], [3 x i8]* %alloca, i64 0, i64 2 + %bc2 = bitcast i8* %gep2 to i16* + %load = load i16, i16* %bc2 + ret i16 %load +}