llvm.org GIT mirror llvm / 3d01334
Fix a bug in the over-index constant folding. When over-indexing an array member of a struct, it's possible to land in an arbitrary position inside that struct, such that attempting to find further getelementptr indices will fail. In such cases, folding cannot be done. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79485 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
2 changed file(s) with 43 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
164164 // Also, this helps GlobalOpt do SROA on GlobalVariables.
165165 const Type *Ty = Ptr->getType();
166166 SmallVector NewIdxs;
167 for (unsigned Index = 1; Index != NumOps; ++Index) {
167 do {
168168 if (const SequentialType *ATy = dyn_cast(Ty)) {
169 // The only pointer indexing we'll do is on the first index of the GEP.
170 if (isa(ATy) && ATy != Ptr->getType())
171 break;
169172 // Determine which element of the array the offset points into.
170173 uint64_t ElemSize = TD->getTypeAllocSize(ATy->getElementType());
171174 if (ElemSize == 0)
182185 Offset -= SL.getElementOffset(ElIdx);
183186 Ty = STy->getTypeAtIndex(ElIdx);
184187 } else {
185 return 0;
186 }
187 }
188 // We've reached some non-indexable type.
189 break;
190 }
191 } while (Ty != cast(ResultTy)->getElementType());
192
193 // If we haven't used up the entire offset by descending the static
194 // type, then the offset is pointing into the middle of an indivisible
195 // member, so we can't simplify it.
196 if (Offset != 0)
197 return 0;
188198
189199 // If the base is the start of a GlobalVariable and all the array indices
190200 // remain in their static bounds, the GEP is inbounds. We can check that
191201 // all indices are in bounds by just checking the first index only
192202 // because we've just normalized all the indices.
193 if (isa(Ptr) && NewIdxs[0]->isNullValue())
194 return ConstantExpr::getInBoundsGetElementPtr(Ptr,
195 &NewIdxs[0], NewIdxs.size());
196
197 // Otherwise it may not be inbounds.
198 return ConstantExpr::getGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size());
203 Constant *C = isa(Ptr) && NewIdxs[0]->isNullValue() ?
204 ConstantExpr::getInBoundsGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size()) :
205 ConstantExpr::getGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size());
206 assert(cast(C->getType())->getElementType() == Ty &&
207 "Computed GetElementPtr has unexpected type!");
208
209 // If we ended up indexing a member with a type that doesn't match
210 // type type of what the original indices indexed, add a cast.
211 if (Ty != cast(ResultTy)->getElementType())
212 C = ConstantExpr::getBitCast(C, ResultTy);
213
214 return C;
199215 }
200216
201217 /// FoldBitCast - Constant fold bitcast, symbolically evaluating it with
0 ; RUN: llvm-as < %s | opt -instcombine
1 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
2 target triple = "i386-apple-darwin10.0"
3
4 %0 = type { i8*, [19 x i8] }
5 %1 = type { i8*, [0 x i8] }
6
7 @s = external global %0 ; <%0*> [#uses=1]
8 @"\01LC8" = external constant [17 x i8] ; <[17 x i8]*> [#uses=1]
9
10 define i32 @main() nounwind {
11 entry:
12 %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([17 x i8]* @"\01LC8", i32 0, i32 0), i8* undef, i8* getelementptr (%1* bitcast (%0* @s to %1*), i32 0, i32 1, i32 0)) nounwind ; [#uses=0]
13 ret i32 0
14 }
15
16 declare i32 @printf(i8*, ...) nounwind