Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 02bf98a

Browse files
committed
This just in, it is a *bad idea* to use 'udiv' on an offset of
a pointer. A very bad idea. Let's not do that. Fixes PR14105. Note that this wasn't *that* glaring of an oversight. Originally, these routines were only called on offsets within an alloca, which are intrinsically positive. But over the evolution of the pass, they ended up being called for arbitrary offsets, and things went downhill... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166095 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 80668fb commit 02bf98a

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

lib/Transforms/Scalar/SROA.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ static Value *getNaturalGEPRecursively(IRBuilder<> &IRB, const DataLayout &TD,
18281828
if (ElementSizeInBits % 8)
18291829
return 0; // GEPs over non-multiple of 8 size vector elements are invalid.
18301830
APInt ElementSize(Offset.getBitWidth(), ElementSizeInBits / 8);
1831-
APInt NumSkippedElements = Offset.udiv(ElementSize);
1831+
APInt NumSkippedElements = Offset.sdiv(ElementSize);
18321832
if (NumSkippedElements.ugt(VecTy->getNumElements()))
18331833
return 0;
18341834
Offset -= NumSkippedElements * ElementSize;
@@ -1840,7 +1840,7 @@ static Value *getNaturalGEPRecursively(IRBuilder<> &IRB, const DataLayout &TD,
18401840
if (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) {
18411841
Type *ElementTy = ArrTy->getElementType();
18421842
APInt ElementSize(Offset.getBitWidth(), TD.getTypeAllocSize(ElementTy));
1843-
APInt NumSkippedElements = Offset.udiv(ElementSize);
1843+
APInt NumSkippedElements = Offset.sdiv(ElementSize);
18441844
if (NumSkippedElements.ugt(ArrTy->getNumElements()))
18451845
return 0;
18461846

@@ -1896,7 +1896,7 @@ static Value *getNaturalGEPWithOffset(IRBuilder<> &IRB, const DataLayout &TD,
18961896
APInt ElementSize(Offset.getBitWidth(), TD.getTypeAllocSize(ElementTy));
18971897
if (ElementSize == 0)
18981898
return 0; // Zero-length arrays can't help us build a natural GEP.
1899-
APInt NumSkippedElements = Offset.udiv(ElementSize);
1899+
APInt NumSkippedElements = Offset.sdiv(ElementSize);
19001900

19011901
Offset -= NumSkippedElements * ElementSize;
19021902
Indices.push_back(IRB.getInt(NumSkippedElements));

test/Transforms/SROA/basictest.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,3 +1063,23 @@ entry:
10631063
call void @llvm.lifetime.end(i64 -1, i8* %0)
10641064
ret void
10651065
}
1066+
1067+
define void @PR14105({ [16 x i8] }* %ptr) {
1068+
; Ensure that when rewriting the GEP index '-1' for this alloca we preserve is
1069+
; sign as negative. We use a volatile memcpy to ensure promotion never actually
1070+
; occurs.
1071+
; CHECK: @PR14105
1072+
1073+
entry:
1074+
%a = alloca { [16 x i8] }, align 8
1075+
; CHECK: alloca [16 x i8], align 8
1076+
1077+
%gep = getelementptr inbounds { [16 x i8] }* %ptr, i64 -1
1078+
; CHECK-NEXT: getelementptr inbounds { [16 x i8] }* %ptr, i64 -1, i32 0, i64 0
1079+
1080+
%cast1 = bitcast { [16 x i8 ] }* %gep to i8*
1081+
%cast2 = bitcast { [16 x i8 ] }* %a to i8*
1082+
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %cast1, i8* %cast2, i32 16, i32 8, i1 true)
1083+
ret void
1084+
; CHECK: ret
1085+
}

0 commit comments

Comments
 (0)