From: Nikita Popov Date: Fri, 1 Jul 2022 12:27:38 +0000 (+0200) Subject: [SimplifyLibCalls] Use inbounds GEP X-Git-Tag: upstream/15.0.7~2884 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fabe915705472e2c06ed1aa9a90620462594e82f;p=platform%2Fupstream%2Fllvm.git [SimplifyLibCalls] Use inbounds GEP When converting strchr(p, '\0') to p + strlen(p) we know that strlen() must return an offset that is inbounds of the allocated object (otherwise it would be UB), so we can use an inbounds GEP. An equivalent argument can be made for the other cases. --- diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index ba659c6..1ff3798 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -242,7 +242,7 @@ Value *LibCallSimplifier::emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, // 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. @@ -326,7 +326,7 @@ Value *LibCallSimplifier::optimizeStrChr(CallInst *CI, IRBuilderBase &B) { 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; } @@ -339,7 +339,7 @@ Value *LibCallSimplifier::optimizeStrChr(CallInst *CI, IRBuilderBase &B) { 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) { @@ -367,7 +367,7 @@ 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) { @@ -564,8 +564,8 @@ Value *LibCallSimplifier::optimizeStpCpy(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. @@ -799,8 +799,8 @@ Value *LibCallSimplifier::optimizeStrPBrk(CallInst *CI, IRBuilderBase &B) { 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') @@ -975,18 +975,17 @@ Value *LibCallSimplifier::optimizeMemRChr(CallInst *CI, IRBuilderBase &B) { 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"); } } @@ -1007,7 +1006,8 @@ Value *LibCallSimplifier::optimizeMemRChr(CallInst *CI, IRBuilderBase &B) { 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"); } @@ -1054,8 +1054,8 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilderBase &B) { // 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); } @@ -2723,7 +2723,7 @@ Value *LibCallSimplifier::optimizeSPrintFString(CallInst *CI, 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); @@ -2863,7 +2863,7 @@ Value *LibCallSimplifier::optimizeSnPrintFString(CallInst *CI, 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); @@ -3599,7 +3599,8 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, // 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(Ret)); } diff --git a/llvm/test/Transforms/InstCombine/memrchr-4.ll b/llvm/test/Transforms/InstCombine/memrchr-4.ll index e6ebb32..c5043b8 100644 --- a/llvm/test/Transforms/InstCombine/memrchr-4.ll +++ b/llvm/test/Transforms/InstCombine/memrchr-4.ll @@ -36,7 +36,7 @@ define i8* @fold_memrchr_a11111_c_n(i32 %C, i64 %N) { ; 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]] ; diff --git a/llvm/test/Transforms/InstCombine/memset_chk-1.ll b/llvm/test/Transforms/InstCombine/memset_chk-1.ll index 8e50d4c..03f8cf3 100644 --- a/llvm/test/Transforms/InstCombine/memset_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/memset_chk-1.ll @@ -83,8 +83,8 @@ define i8* @test_no_simplify2() { 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 @@ -100,7 +100,7 @@ define i32 @test_rauw(i8* %a, i8* %b, i8** %c) { ; 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 @@ -136,13 +136,13 @@ declare i8* @__memset_chk(i8*, i32, i64, 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:%.*]] ] diff --git a/llvm/test/Transforms/InstCombine/snprintf.ll b/llvm/test/Transforms/InstCombine/snprintf.ll index d7c1361..3076355 100644 --- a/llvm/test/Transforms/InstCombine/snprintf.ll +++ b/llvm/test/Transforms/InstCombine/snprintf.ll @@ -104,7 +104,7 @@ define i32 @test_char_wrong_size(i8* %buf) #0 { 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 ; @@ -142,7 +142,7 @@ define i32 @test_str_ok_size(i8* %buf) #0 { ; 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)) @@ -151,8 +151,8 @@ define i32 @test_str_ok_size_tail(i8* %buf) { 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 @@ -171,8 +171,8 @@ define i32 @test_str_ok_size_tail2(i8* %buf) { 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 diff --git a/llvm/test/Transforms/InstCombine/sprintf-1.ll b/llvm/test/Transforms/InstCombine/sprintf-1.ll index 289a5c7..9a7bffc 100644 --- a/llvm/test/Transforms/InstCombine/sprintf-1.ll +++ b/llvm/test/Transforms/InstCombine/sprintf-1.ll @@ -59,7 +59,7 @@ define void @test_simplify3(i8* %dst) { 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 ; diff --git a/llvm/test/Transforms/InstCombine/strchr-1.ll b/llvm/test/Transforms/InstCombine/strchr-1.ll index cb6b3ad..1e771859 100644 --- a/llvm/test/Transforms/InstCombine/strchr-1.ll +++ b/llvm/test/Transforms/InstCombine/strchr-1.ll @@ -76,7 +76,7 @@ define void @test_simplify5() { 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 ; diff --git a/llvm/test/Transforms/InstCombine/strncat-2.ll b/llvm/test/Transforms/InstCombine/strncat-2.ll index 1665fc1..9c842f6 100644 --- a/llvm/test/Transforms/InstCombine/strncat-2.ll +++ b/llvm/test/Transforms/InstCombine/strncat-2.ll @@ -13,7 +13,7 @@ declare i8* @strncat(i8*, i8*, i32) 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 ; @@ -103,7 +103,7 @@ define i8* @test4(i8* %str1, i8* %str2, i32 %n) null_pointer_is_valid { 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]] ;