[llvm] ab7ee3c - [InstCombine] Enable strtol folding with nonnull endptr
Martin Sebor via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 13 08:27:54 PDT 2022
Author: Martin Sebor
Date: 2022-07-13T09:26:34-06:00
New Revision: ab7ee3c9911ff90bb209213b1385336f1619d174
URL: https://github.com/llvm/llvm-project/commit/ab7ee3c9911ff90bb209213b1385336f1619d174
DIFF: https://github.com/llvm/llvm-project/commit/ab7ee3c9911ff90bb209213b1385336f1619d174.diff
LOG: [InstCombine] Enable strtol folding with nonnull endptr
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D129593
Added:
Modified:
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/test/Transforms/InstCombine/str-int-2.ll
llvm/test/Transforms/InstCombine/str-int.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index eafb17c1c50b7..b359717424a6a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -75,7 +75,8 @@ static bool callHasFP128Argument(const CallInst *CI) {
});
}
-static Value *convertStrToNumber(CallInst *CI, StringRef &Str, int64_t Base) {
+static Value *convertStrToNumber(CallInst *CI, StringRef &Str, Value *EndPtr,
+ int64_t Base, IRBuilderBase &B) {
if (Base < 2 || Base > 36)
// handle special zero base
if (Base != 0)
@@ -97,6 +98,15 @@ static Value *convertStrToNumber(CallInst *CI, StringRef &Str, int64_t Base) {
if (!isIntN(CI->getType()->getPrimitiveSizeInBits(), Result))
return nullptr;
+ if (EndPtr) {
+ // Store the pointer to the end.
+ uint64_t ILen = End - nptr.c_str();
+ Value *Off = B.getInt64(ILen);
+ Value *StrBeg = CI->getArgOperand(0);
+ Value *StrEnd = B.CreateInBoundsGEP(B.getInt8Ty(), StrBeg, Off, "endptr");
+ B.CreateStore(StrEnd, EndPtr);
+ }
+
return ConstantInt::get(CI->getType(), Result);
}
@@ -2523,7 +2533,7 @@ Value *LibCallSimplifier::optimizeAtoi(CallInst *CI, IRBuilderBase &B) {
if (!getConstantStringInfo(CI->getArgOperand(0), Str))
return nullptr;
- return convertStrToNumber(CI, Str, 10);
+ return convertStrToNumber(CI, Str, nullptr, 10, B);
}
Value *LibCallSimplifier::optimizeStrtol(CallInst *CI, IRBuilderBase &B) {
@@ -2531,11 +2541,14 @@ Value *LibCallSimplifier::optimizeStrtol(CallInst *CI, IRBuilderBase &B) {
if (!getConstantStringInfo(CI->getArgOperand(0), Str))
return nullptr;
- if (!isa<ConstantPointerNull>(CI->getArgOperand(1)))
+ Value *EndPtr = CI->getArgOperand(1);
+ if (isa<ConstantPointerNull>(EndPtr))
+ EndPtr = nullptr;
+ else if (!isKnownNonZero(EndPtr, DL))
return nullptr;
if (ConstantInt *CInt = dyn_cast<ConstantInt>(CI->getArgOperand(2))) {
- return convertStrToNumber(CI, Str, CInt->getSExtValue());
+ return convertStrToNumber(CI, Str, EndPtr, CInt->getSExtValue(), B);
}
return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/str-int-2.ll b/llvm/test/Transforms/InstCombine/str-int-2.ll
index 290c3398f241a..d81ecbb774029 100644
--- a/llvm/test/Transforms/InstCombine/str-int-2.ll
+++ b/llvm/test/Transforms/InstCombine/str-int-2.ll
@@ -40,14 +40,25 @@ define i64 @strtol_hex() #0 {
ret i64 %call
}
-define i64 @strtol_endptr_not_null() #0 {
+; Fold a call to strtol with an endptr known to be nonnull.
+
+define i64 @strtol_endptr_not_null(i8** nonnull %pend) {
; CHECK-LABEL: @strtol_endptr_not_null(
-; CHECK-NEXT: [[END:%.*]] = alloca i8*, align 4
-; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** nonnull [[END]], i32 10)
+; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 2), i8** [[PEND:%.*]], align 8
+; CHECK-NEXT: ret i64 12
+;
+ %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** %pend, i32 10)
+ ret i64 %call
+}
+
+; Don't fold a call to strtol with an endptr that's not known to be nonnull.
+
+define i64 @strtol_endptr_maybe_null(i8** %end) {
+; CHECK-LABEL: @strtol_endptr_maybe_null(
+; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** [[END:%.*]], i32 10)
; CHECK-NEXT: ret i64 [[CALL]]
;
- %end = alloca i8*, align 4
- %call = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10) #2
+ %call = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10)
ret i64 %call
}
diff --git a/llvm/test/Transforms/InstCombine/str-int.ll b/llvm/test/Transforms/InstCombine/str-int.ll
index 6de0a0795b64b..f74d774b42cbf 100644
--- a/llvm/test/Transforms/InstCombine/str-int.ll
+++ b/llvm/test/Transforms/InstCombine/str-int.ll
@@ -40,14 +40,28 @@ define i32 @strtol_hex() #0 {
ret i32 %call
}
-define i32 @strtol_endptr_not_null() #0 {
+; Fold a call to strtol with an endptr known to be nonnull (the result
+; of pointer increment).
+
+define i32 @strtol_endptr_not_null(i8** %pend) {
; CHECK-LABEL: @strtol_endptr_not_null(
-; CHECK-NEXT: [[END:%.*]] = alloca i8*, align 4
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** nonnull [[END]], i32 10)
+; CHECK-NEXT: [[ENDP1:%.*]] = getelementptr inbounds i8*, i8** [[PEND:%.*]], i64 1
+; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 2), i8** [[ENDP1]], align 8
+; CHECK-NEXT: ret i32 12
+;
+ %endp1 = getelementptr inbounds i8*, i8** %pend, i32 1
+ %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** %endp1, i32 10)
+ ret i32 %call
+}
+
+; Don't fold a call to strtol with an endptr that's not known to be nonnull.
+
+define i32 @strtol_endptr_maybe_null(i8** %end) {
+; CHECK-LABEL: @strtol_endptr_maybe_null(
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** [[END:%.*]], i32 10)
; CHECK-NEXT: ret i32 [[CALL]]
;
- %end = alloca i8*, align 4
- %call = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10) #2
+ %call = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10)
ret i32 %call
}
More information about the llvm-commits
mailing list