// Now that we have the destination's length, we must index into the
// destination's pointer to get the actual memcpy destination (end of
// the string .. we're concatenating).
- Value *CpyDst = B.CreateGEP(B.getInt8Ty(), Dst, DstLen, "endptr");
+ Value *CpyDst = B.CreateInBoundsGEP(B.getInt8Ty(), Dst, DstLen, "endptr");
// We have enough information to now generate the memcpy call to do the
// concatenation for us. Make a memcpy to copy the nul byte with align = 1.
if (!getConstantStringInfo(SrcStr, Str)) {
if (CharC->isZero()) // strchr(p, 0) -> p + strlen(p)
if (Value *StrLen = emitStrLen(SrcStr, B, DL, TLI))
- return B.CreateGEP(B.getInt8Ty(), SrcStr, StrLen, "strchr");
+ return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, StrLen, "strchr");
return nullptr;
}
return Constant::getNullValue(CI->getType());
// strchr(s+n,c) -> gep(s+n+i,c)
- return B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "strchr");
+ return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "strchr");
}
Value *LibCallSimplifier::optimizeStrRChr(CallInst *CI, IRBuilderBase &B) {
return Constant::getNullValue(CI->getType());
// strrchr(s+n,c) -> gep(s+n+i,c)
- return B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "strrchr");
+ return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "strrchr");
}
Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilderBase &B) {
Type *PT = Callee->getFunctionType()->getParamType(0);
Value *LenV = ConstantInt::get(DL.getIntPtrType(PT), Len);
- Value *DstEnd = B.CreateGEP(B.getInt8Ty(), Dst,
- ConstantInt::get(DL.getIntPtrType(PT), Len - 1));
+ Value *DstEnd = B.CreateInBoundsGEP(
+ B.getInt8Ty(), Dst, ConstantInt::get(DL.getIntPtrType(PT), Len - 1));
// We have enough information to now generate the memcpy call to do the
// copy for us. Make a memcpy to copy the nul byte with align = 1.
if (I == StringRef::npos) // No match.
return Constant::getNullValue(CI->getType());
- return B.CreateGEP(B.getInt8Ty(), CI->getArgOperand(0), B.getInt64(I),
- "strpbrk");
+ return B.CreateInBoundsGEP(B.getInt8Ty(), CI->getArgOperand(0),
+ B.getInt64(I), "strpbrk");
}
// strpbrk(s, "a") -> strchr(s, 'a')
if (LenC)
// Fold memrchr(s, c, N) --> s + Pos for constant N > Pos.
- return B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos));
+ return B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos));
if (Str.find(Str[Pos]) == Pos) {
// When there is just a single occurrence of C in S, i.e., the one
// in Str[Pos], fold
// memrchr(s, c, N) --> N <= Pos ? null : s + Pos
// for nonconstant N.
- Value *Cmp = B.CreateICmpULE(Size, ConstantInt::get(Size->getType(),
- Pos),
+ Value *Cmp = B.CreateICmpULE(Size, ConstantInt::get(Size->getType(), Pos),
"memrchr.cmp");
- Value *SrcPlus = B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos),
- "memrchr.ptr_plus");
+ Value *SrcPlus = B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr,
+ B.getInt64(Pos), "memrchr.ptr_plus");
return B.CreateSelect(Cmp, NullPtr, SrcPlus, "memrchr.sel");
}
}
Value *CEqS0 = B.CreateICmpEQ(ConstantInt::get(Int8Ty, Str[0]), CharVal);
Value *And = B.CreateLogicalAnd(NNeZ, CEqS0);
Value *SizeM1 = B.CreateSub(Size, ConstantInt::get(SizeTy, 1));
- Value *SrcPlus = B.CreateGEP(Int8Ty, SrcStr, SizeM1, "memrchr.ptr_plus");
+ Value *SrcPlus =
+ B.CreateInBoundsGEP(Int8Ty, SrcStr, SizeM1, "memrchr.ptr_plus");
return B.CreateSelect(And, SrcPlus, NullPtr, "memrchr.sel");
}
// position also fold the result to null.
Value *Cmp = B.CreateICmpULE(Size, ConstantInt::get(Size->getType(), Pos),
"memchr.cmp");
- Value *SrcPlus =
- B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos), "memchr.ptr");
+ Value *SrcPlus = B.CreateInBoundsGEP(B.getInt8Ty(), SrcStr, B.getInt64(Pos),
+ "memchr.ptr");
return B.CreateSelect(Cmp, NullPtr, SrcPlus);
}
Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char");
Value *Ptr = castToCStr(Dest, B);
B.CreateStore(V, Ptr);
- Ptr = B.CreateGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
+ Ptr = B.CreateInBoundsGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
B.CreateStore(B.getInt8(0), Ptr);
return ConstantInt::get(CI->getType(), 1);
Value *V = B.CreateTrunc(CI->getArgOperand(3), B.getInt8Ty(), "char");
Value *Ptr = castToCStr(CI->getArgOperand(0), B);
B.CreateStore(V, Ptr);
- Ptr = B.CreateGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
+ Ptr = B.CreateInBoundsGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul");
B.CreateStore(B.getInt8(0), Ptr);
return ConstantInt::get(CI->getType(), 1);
// If the function was an __stpcpy_chk, and we were able to fold it into
// a __memcpy_chk, we still need to return the correct end pointer.
if (Ret && Func == LibFunc_stpcpy_chk)
- return B.CreateGEP(B.getInt8Ty(), Dst, ConstantInt::get(SizeTTy, Len - 1));
+ return B.CreateInBoundsGEP(B.getInt8Ty(), Dst,
+ ConstantInt::get(SizeTTy, Len - 1));
return copyFlags(*CI, cast<CallInst>(Ret));
}
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i1 [[TMP3]], i1 false
; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[N]], -1
-; CHECK-NEXT: [[MEMRCHR_PTR_PLUS:%.*]] = getelementptr [5 x i8], [5 x i8]* @a11111, i64 0, i64 [[TMP5]]
+; CHECK-NEXT: [[MEMRCHR_PTR_PLUS:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* @a11111, i64 0, i64 [[TMP5]]
; CHECK-NEXT: [[MEMRCHR_SEL:%.*]] = select i1 [[TMP4]], i8* [[MEMRCHR_PTR_PLUS]], i8* null
; CHECK-NEXT: ret i8* [[MEMRCHR_SEL]]
;
define i8* @test_no_simplify3(i8* %dst, i32 %a, i64 %b, i64 %c) {
; CHECK-LABEL: @test_no_simplify3(
-; CHECK-NEXT: %ret = musttail call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
-; CHECK-NEXT: ret i8* %ret
+; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @__memset_chk(i8* [[DST:%.*]], i32 0, i64 1824, i64 1824)
+; CHECK-NEXT: ret i8* [[RET]]
;
%ret = musttail call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
ret i8* %ret
; CHECK-NEXT: [[YO107:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[B:%.*]], i1 false, i1 false, i1 false)
; CHECK-NEXT: [[CALL50:%.*]] = call i8* @__memmove_chk(i8* [[B]], i8* [[A]], i64 [[ADD180]], i64 [[YO107]])
; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[B]])
-; CHECK-NEXT: [[STRCHR1:%.*]] = getelementptr i8, i8* [[B]], i64 [[STRLEN]]
+; CHECK-NEXT: [[STRCHR1:%.*]] = getelementptr inbounds i8, i8* [[B]], i64 [[STRLEN]]
; CHECK-NEXT: [[D:%.*]] = load i8*, i8** [[C:%.*]], align 8
; CHECK-NEXT: [[SUB182:%.*]] = ptrtoint i8* [[D]] to i64
; CHECK-NEXT: [[SUB183:%.*]] = ptrtoint i8* [[B]] to i64
define float* @pr25892(i64 %size) #0 {
; CHECK-LABEL: @pr25892(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i64 [[SIZE:%.*]]) [[ATTR3:#.*]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i64 [[SIZE:%.*]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[CALL]], null
; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[CALL]] to float*
; CHECK-NEXT: [[CALL2:%.*]] = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull [[CALL]], i1 false, i1 false, i1 false)
-; CHECK-NEXT: [[CALL3:%.*]] = tail call i8* @__memset_chk(i8* nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) [[ATTR3]]
+; CHECK-NEXT: [[CALL3:%.*]] = tail call i8* @__memset_chk(i8* nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) #[[ATTR3]]
; CHECK-NEXT: br label [[CLEANUP]]
; CHECK: cleanup:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
define i32 @test_char_ok_size(i8* %buf) #0 {
; CHECK-LABEL: @test_char_ok_size(
; CHECK-NEXT: store i8 65, i8* [[BUF:%.*]], align 1
-; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[BUF]], i64 1
+; CHECK-NEXT: [[NUL:%.*]] = getelementptr inbounds i8, i8* [[BUF]], i64 1
; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
; CHECK-NEXT: ret i32 1
;
; snprintf(buf, 32, "") -> memcpy -> store
define i32 @test_str_ok_size_tail(i8* %buf) {
; CHECK-LABEL: @test_str_ok_size_tail(
-; CHECK-NEXT: store i8 0, i8* %buf, align 1
+; CHECK-NEXT: store i8 0, i8* [[BUF:%.*]], align 1
; CHECK-NEXT: ret i32 0
;
%1 = tail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0))
define i32 @test_str_ok_size_musttail(i8* %buf, i64 %x, i8* %y, ...) {
; CHECK-LABEL: @test_str_ok_size_musttail(
-; CHECK-NEXT: %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...)
-; CHECK-NEXT: ret i32 %1
+; CHECK-NEXT: [[TMP1:%.*]] = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...)
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...)
ret i32 %1
define i32 @test_str_ok_size_musttail2(i8* %buf, i64 %x, i8* %y, ...) {
; CHECK-LABEL: @test_str_ok_size_musttail2(
-; CHECK-NEXT: %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...)
-; CHECK-NEXT: ret i32 %1
+; CHECK-NEXT: [[TMP1:%.*]] = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...)
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...)
ret i32 %1
define void @test_simplify4(i8* %dst) {
; CHECK-LABEL: @test_simplify4(
; CHECK-NEXT: store i8 104, i8* [[DST:%.*]], align 1
-; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[DST]], i32 1
+; CHECK-NEXT: [[NUL:%.*]] = getelementptr inbounds i8, i8* [[DST]], i32 1
; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
; CHECK-NEXT: ret void
;
define void @test_simplify6(i8* %str) {
; CHECK-LABEL: @test_simplify6(
; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]])
-; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr i8, i8* [[STR]], i32 [[STRLEN]]
+; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr inbounds i8, i8* [[STR]], i32 [[STRLEN]]
; CHECK-NEXT: store i8* [[STRCHR]], i8** @chp, align 4
; CHECK-NEXT: ret void
;
define void @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0))
-; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 [[STRLEN]]
+; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @a, i32 0, i32 [[STRLEN]]
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false)
; CHECK-NEXT: ret void
;
define i8* @test5(i8* %str, i32 %n) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]])
-; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr i8, i8* [[STR]], i32 [[STRLEN]]
+; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, i8* [[STR]], i32 [[STRLEN]]
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false)
; CHECK-NEXT: ret i8* [[STR]]
;