Skip to content

Commit a6d4017

Browse files
authored
[StackSafetyAnalysis] Bail out if MemIntrinsic length is -1 (llvm#77837)
Clang generates llvm.memset.p0.i64 with a length of -1 for the following code in `-stdlib=libc++ -std=c++20` mode (llvm#77210 (comment)) ```cpp bool strtof_clamp(const std::string &str); void floatsuffix_check(char *yytext_r) { std::string text = yytext_r; text.resize(text.size() - 1); strtof_clamp(text); } ``` `Sizes = [0xffffffffffffffff, 0)`. `SizeRange = [0, 0-1)`, leading to `assert(!isUnsafe(SizeRange));` failure. Bail out if the length is -1. Other negative values are handled by the existing condition.
1 parent 238b579 commit a6d4017

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/lib/Analysis/StackSafetyAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
331331
const SCEV *Expr =
332332
SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
333333
ConstantRange Sizes = SE.getSignedRange(Expr);
334-
if (Sizes.getUpper().isNegative() || isUnsafe(Sizes))
334+
if (!Sizes.getUpper().isStrictlyPositive() || isUnsafe(Sizes))
335335
return UnknownRange;
336336
Sizes = Sizes.sextOrTrunc(PointerSize);
337337
ConstantRange SizeRange(APInt::getZero(PointerSize), Sizes.getUpper() - 1);

llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,40 @@ entry:
9898
ret void
9999
}
100100

101+
define void @MemsetHugeUpper_m1(i1 %bool) {
102+
; CHECK-LABEL: MemsetHugeUpper_m1 dso_preemptable{{$}}
103+
; CHECK-NEXT: args uses:
104+
; CHECK-NEXT: allocas uses:
105+
; CHECK-NEXT: x[4]: full-set
106+
entry:
107+
%x = alloca i32, align 4
108+
br i1 %bool, label %if.then, label %if.end
109+
110+
if.then:
111+
call void @llvm.memset.p0.i64(ptr %x, i8 0, i64 -1, i1 false)
112+
br label %if.end
113+
114+
if.end:
115+
ret void
116+
}
117+
118+
define void @MemsetHugeUpper_m2(i1 %bool) {
119+
; CHECK-LABEL: MemsetHugeUpper_m2 dso_preemptable{{$}}
120+
; CHECK-NEXT: args uses:
121+
; CHECK-NEXT: allocas uses:
122+
; CHECK-NEXT: x[4]: full-set
123+
entry:
124+
%x = alloca i32, align 4
125+
br i1 %bool, label %if.then, label %if.end
126+
127+
if.then:
128+
call void @llvm.memset.p0.i64(ptr %x, i8 0, i64 -2, i1 false)
129+
br label %if.end
130+
131+
if.end:
132+
ret void
133+
}
134+
101135
define void @MemcpyInBounds() {
102136
; CHECK-LABEL: MemcpyInBounds dso_preemptable{{$}}
103137
; CHECK-NEXT: args uses:

0 commit comments

Comments
 (0)