Skip to content

Commit e2d3521

Browse files
committed
[AggressiveInstCombine] Inline strcmp/strncmp
* add missing test cases * remove redundant code
1 parent 9726bd4 commit e2d3521

File tree

3 files changed

+78
-63
lines changed

3 files changed

+78
-63
lines changed

llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,18 +1055,17 @@ bool StrNCmpInliner::optimizeStrNCmp() {
10551055
///
10561056
bool StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
10571057
bool Switched) {
1058-
IRBuilder<> B(CI->getContext());
1058+
auto &Ctx = CI->getContext();
1059+
IRBuilder<> B(Ctx);
10591060

10601061
BasicBlock *BBCI = CI->getParent();
1061-
bool IsEntry = BBCI->isEntryBlock();
10621062
BasicBlock *BBBefore = splitBlockBefore(BBCI, CI, DTU, nullptr, nullptr,
10631063
BBCI->getName() + ".before");
10641064

10651065
SmallVector<BasicBlock *> BBSubs;
1066-
for (uint64_t i = 0; i < N + 1; ++i)
1067-
BBSubs.push_back(
1068-
BasicBlock::Create(CI->getContext(), "sub", BBCI->getParent(), BBCI));
1069-
BasicBlock *BBNE = BBSubs[N];
1066+
for (uint64_t i = 0; i < N; ++i)
1067+
BBSubs.push_back(BasicBlock::Create(Ctx, "sub", BBCI->getParent(), BBCI));
1068+
BasicBlock *BBNE = BasicBlock::Create(Ctx, "ne", BBCI->getParent(), BBCI);
10701069

10711070
cast<BranchInst>(BBBefore->getTerminator())->setSuccessor(0, BBSubs[0]);
10721071

@@ -1099,27 +1098,23 @@ bool StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
10991098

11001099
// Update DomTree
11011100
if (DTU) {
1102-
if (IsEntry) {
1103-
DTU->recalculate(*BBCI->getParent());
1104-
} else {
1105-
SmallVector<DominatorTree::UpdateType, 8> Updates;
1106-
Updates.push_back({DominatorTree::Delete, BBBefore, BBCI});
1107-
Updates.push_back({DominatorTree::Insert, BBBefore, BBSubs[0]});
1108-
for (uint64_t i = 0; i < N; ++i) {
1109-
if (i < N - 1)
1110-
Updates.push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
1111-
Updates.push_back({DominatorTree::Insert, BBSubs[i], BBNE});
1112-
}
1113-
Updates.push_back({DominatorTree::Insert, BBNE, BBCI});
1114-
DTU->applyUpdates(Updates);
1101+
SmallVector<DominatorTree::UpdateType, 8> Updates;
1102+
Updates.push_back({DominatorTree::Delete, BBBefore, BBCI});
1103+
Updates.push_back({DominatorTree::Insert, BBBefore, BBSubs[0]});
1104+
for (uint64_t i = 0; i < N; ++i) {
1105+
if (i < N - 1)
1106+
Updates.push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
1107+
Updates.push_back({DominatorTree::Insert, BBSubs[i], BBNE});
11151108
}
1109+
Updates.push_back({DominatorTree::Insert, BBNE, BBCI});
1110+
DTU->applyUpdates(Updates);
11161111
}
11171112
return true;
11181113
}
11191114

11201115
static bool inlineLibCalls(Function &F, TargetLibraryInfo &TLI,
11211116
const TargetTransformInfo &TTI, DominatorTree &DT,
1122-
bool &MadeCFGChange) {
1117+
const DataLayout &DL, bool &MadeCFGChange) {
11231118
MadeCFGChange = false;
11241119
DomTreeUpdater DTU(&DT, DomTreeUpdater::UpdateStrategy::Lazy);
11251120

@@ -1137,20 +1132,13 @@ static bool inlineLibCalls(Function &F, TargetLibraryInfo &TLI,
11371132
if (!Call || !(CalledFunc = Call->getCalledFunction()))
11381133
continue;
11391134

1140-
if (Call->isNoBuiltin())
1141-
continue;
1142-
1143-
// Skip if function either has local linkage or is not a known library
1144-
// function.
11451135
LibFunc LF;
1146-
if (CalledFunc->hasLocalLinkage() || !TLI.getLibFunc(*CalledFunc, LF) ||
1147-
!TLI.has(LF))
1136+
if (!TLI.getLibFunc(*CalledFunc, LF))
11481137
continue;
11491138

11501139
switch (LF) {
11511140
case LibFunc_strcmp:
11521141
case LibFunc_strncmp: {
1153-
auto &DL = F.getParent()->getDataLayout();
11541142
if (StrNCmpInliner(Call, LF, BB, &DTU, DL).optimizeStrNCmp()) {
11551143
MadeCFGChange = true;
11561144
break;
@@ -1221,7 +1209,7 @@ static bool runImpl(Function &F, AssumptionCache &AC, TargetTransformInfo &TTI,
12211209
const DataLayout &DL = F.getParent()->getDataLayout();
12221210
TruncInstCombine TIC(AC, TLI, DL, DT);
12231211
MadeChange |= TIC.run(F);
1224-
MadeChange |= inlineLibCalls(F, TLI, TTI, DT, MadeCFGChange);
1212+
MadeChange |= inlineLibCalls(F, TLI, TTI, DT, DL, MadeCFGChange);
12251213
MadeChange |= foldUnusualPatterns(F, DT, TTI, TLI, AA, AC);
12261214
return MadeChange;
12271215
}

llvm/test/Transforms/AggressiveInstCombine/strncmp-1.ll

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
12
; RUN: opt -S -passes=aggressive-instcombine -strncmp-inline-threshold=3 < %s | FileCheck %s
23

34
declare i32 @strncmp(ptr nocapture, ptr nocapture, i64)
@@ -7,23 +8,24 @@ declare i32 @strcmp(ptr nocapture, ptr nocapture)
78
@.str.1 = private unnamed_addr constant [2 x i8] c"a\00", align 1
89

910
define i32 @test_strncmp_1(ptr nocapture readonly %s) {
10-
; CHECK-LABEL: @test_strncmp_1(
11+
; CHECK-LABEL: define i32 @test_strncmp_1(
12+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
1113
; CHECK-NEXT: entry.before:
1214
; CHECK-NEXT: br label [[SUB:%.*]]
1315
; CHECK: sub:
14-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
16+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
1517
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
1618
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
1719
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 97, [[TMP2]]
1820
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
19-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB2:%.*]], label [[SUB1:%.*]]
21+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
2022
; CHECK: sub1:
2123
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
2224
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
2325
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
2426
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 98, [[TMP7]]
25-
; CHECK-NEXT: br label [[SUB2]]
26-
; CHECK: sub2:
27+
; CHECK-NEXT: br label [[NE]]
28+
; CHECK: ne:
2729
; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ]
2830
; CHECK-NEXT: br label [[ENTRY:%.*]]
2931
; CHECK: entry:
@@ -35,30 +37,31 @@ entry:
3537
}
3638

3739
define i32 @test_strncmp_2(ptr nocapture readonly %s) {
38-
; CHECK-LABEL: @test_strncmp_2(
40+
; CHECK-LABEL: define i32 @test_strncmp_2(
41+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
3942
; CHECK-NEXT: entry.before:
4043
; CHECK-NEXT: br label [[SUB:%.*]]
4144
; CHECK: sub:
42-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
45+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
4346
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
4447
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
4548
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 97, [[TMP2]]
4649
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
47-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB3:%.*]], label [[SUB1:%.*]]
50+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
4851
; CHECK: sub1:
4952
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
5053
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
5154
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
5255
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 98, [[TMP7]]
5356
; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i32 [[TMP8]], 0
54-
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB3]], label [[SUB2:%.*]]
57+
; CHECK-NEXT: br i1 [[TMP9]], label [[NE]], label [[SUB2:%.*]]
5558
; CHECK: sub2:
5659
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 2
5760
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
5861
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
5962
; CHECK-NEXT: [[TMP13:%.*]] = sub i32 0, [[TMP12]]
60-
; CHECK-NEXT: br label [[SUB3]]
61-
; CHECK: sub3:
63+
; CHECK-NEXT: br label [[NE]]
64+
; CHECK: ne:
6265
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ], [ [[TMP13]], [[SUB2]] ]
6366
; CHECK-NEXT: br label [[ENTRY:%.*]]
6467
; CHECK: entry:
@@ -70,30 +73,31 @@ entry:
7073
}
7174

7275
define i32 @test_strncmp_3(ptr nocapture readonly %s) {
73-
; CHECK-LABEL: @test_strncmp_3(
76+
; CHECK-LABEL: define i32 @test_strncmp_3(
77+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
7478
; CHECK-NEXT: entry.before:
7579
; CHECK-NEXT: br label [[SUB:%.*]]
7680
; CHECK: sub:
77-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
81+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
7882
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
7983
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
8084
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 97, [[TMP2]]
8185
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
82-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB3:%.*]], label [[SUB1:%.*]]
86+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
8387
; CHECK: sub1:
8488
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
8589
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
8690
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
8791
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 98, [[TMP7]]
8892
; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i32 [[TMP8]], 0
89-
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB3]], label [[SUB2:%.*]]
93+
; CHECK-NEXT: br i1 [[TMP9]], label [[NE]], label [[SUB2:%.*]]
9094
; CHECK: sub2:
9195
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 2
9296
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
9397
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
9498
; CHECK-NEXT: [[TMP13:%.*]] = sub i32 0, [[TMP12]]
95-
; CHECK-NEXT: br label [[SUB3]]
96-
; CHECK: sub3:
99+
; CHECK-NEXT: br label [[NE]]
100+
; CHECK: ne:
97101
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ], [ [[TMP13]], [[SUB2]] ]
98102
; CHECK-NEXT: br label [[ENTRY:%.*]]
99103
; CHECK: entry:
@@ -105,23 +109,24 @@ entry:
105109
}
106110

107111
define i32 @test_strcmp_1(ptr nocapture readonly %s) {
108-
; CHECK-LABEL: @test_strcmp_1(
112+
; CHECK-LABEL: define i32 @test_strcmp_1(
113+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
109114
; CHECK-NEXT: entry.before:
110115
; CHECK-NEXT: br label [[SUB:%.*]]
111116
; CHECK: sub:
112-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
117+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
113118
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
114119
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
115120
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], 97
116121
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
117-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB2:%.*]], label [[SUB1:%.*]]
122+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
118123
; CHECK: sub1:
119124
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
120125
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
121126
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
122127
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 [[TMP7]], 0
123-
; CHECK-NEXT: br label [[SUB2]]
124-
; CHECK: sub2:
128+
; CHECK-NEXT: br label [[NE]]
129+
; CHECK: ne:
125130
; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ]
126131
; CHECK-NEXT: br label [[ENTRY:%.*]]
127132
; CHECK: entry:
@@ -133,30 +138,31 @@ entry:
133138
}
134139

135140
define i32 @test_strcmp_2(ptr nocapture readonly %s) {
136-
; CHECK-LABEL: @test_strcmp_2(
141+
; CHECK-LABEL: define i32 @test_strcmp_2(
142+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
137143
; CHECK-NEXT: entry.before:
138144
; CHECK-NEXT: br label [[SUB:%.*]]
139145
; CHECK: sub:
140-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
146+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
141147
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
142148
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
143149
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], 97
144150
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
145-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB3:%.*]], label [[SUB1:%.*]]
151+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
146152
; CHECK: sub1:
147153
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
148154
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
149155
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
150156
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 [[TMP7]], 98
151157
; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i32 [[TMP8]], 0
152-
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB3]], label [[SUB2:%.*]]
158+
; CHECK-NEXT: br i1 [[TMP9]], label [[NE]], label [[SUB2:%.*]]
153159
; CHECK: sub2:
154160
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 2
155161
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
156162
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
157163
; CHECK-NEXT: [[TMP13:%.*]] = sub i32 [[TMP12]], 0
158-
; CHECK-NEXT: br label [[SUB3]]
159-
; CHECK: sub3:
164+
; CHECK-NEXT: br label [[NE]]
165+
; CHECK: ne:
160166
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ], [ [[TMP13]], [[SUB2]] ]
161167
; CHECK-NEXT: br label [[ENTRY:%.*]]
162168
; CHECK: entry:
@@ -168,30 +174,31 @@ entry:
168174
}
169175

170176
define i32 @test_strcmp_3(ptr nocapture readonly %s) {
171-
; CHECK-LABEL: @test_strcmp_3(
177+
; CHECK-LABEL: define i32 @test_strcmp_3(
178+
; CHECK-SAME: ptr nocapture readonly [[S:%.*]]) {
172179
; CHECK-NEXT: entry.before:
173180
; CHECK-NEXT: br label [[SUB:%.*]]
174181
; CHECK: sub:
175-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i64 0
182+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 0
176183
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1
177184
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
178185
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 97, [[TMP2]]
179186
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
180-
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB3:%.*]], label [[SUB1:%.*]]
187+
; CHECK-NEXT: br i1 [[TMP4]], label [[NE:%.*]], label [[SUB1:%.*]]
181188
; CHECK: sub1:
182189
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 1
183190
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
184191
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
185192
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 98, [[TMP7]]
186193
; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i32 [[TMP8]], 0
187-
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB3]], label [[SUB2:%.*]]
194+
; CHECK-NEXT: br i1 [[TMP9]], label [[NE]], label [[SUB2:%.*]]
188195
; CHECK: sub2:
189196
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[S]], i64 2
190197
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
191198
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
192199
; CHECK-NEXT: [[TMP13:%.*]] = sub i32 0, [[TMP12]]
193-
; CHECK-NEXT: br label [[SUB3]]
194-
; CHECK: sub3:
200+
; CHECK-NEXT: br label [[NE]]
201+
; CHECK: ne:
195202
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ [[TMP3]], [[SUB]] ], [ [[TMP8]], [[SUB1]] ], [ [[TMP13]], [[SUB2]] ]
196203
; CHECK-NEXT: br label [[ENTRY:%.*]]
197204
; CHECK: entry:

llvm/test/Transforms/AggressiveInstCombine/strncmp-2.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ entry:
2222
; CHECK-LABEL: @test_strncmp_1(
2323
; CHECK-NOT: @strncmp
2424

25+
define i32 @test_strncmp_1_dereferenceable(i8* nocapture readonly dereferenceable(2) %s) {
26+
entry:
27+
%call = tail call i32 @strncmp(ptr nonnull %s, ptr nonnull dereferenceable(3) @.str, i64 2)
28+
%tobool.not = icmp eq i32 %call, 0
29+
%retval.0 = select i1 %tobool.not, i32 11, i32 41
30+
ret i32 %retval.0
31+
}
32+
; CHECK-LABEL: @test_strncmp_1_dereferenceable(
33+
; CHECK: @strncmp
34+
2535
; int test_strncmp_2(const char *s) {
2636
; if (!strncmp(s, "aa", 3))
2737
; return 11;
@@ -129,6 +139,16 @@ entry:
129139
; CHECK-LABEL: @test_strcmp_1(
130140
; CHECK-NOT: @strcmp
131141

142+
define i32 @test_strcmp_1_dereferenceable(i8* nocapture readonly dereferenceable(2) %s) {
143+
entry:
144+
%call = tail call i32 @strcmp(ptr nonnull %s, ptr nonnull dereferenceable(3) @.str)
145+
%tobool.not = icmp eq i32 %call, 0
146+
%retval.0 = select i1 %tobool.not, i32 11, i32 41
147+
ret i32 %retval.0
148+
}
149+
; CHECK-LABEL: @test_strcmp_1_dereferenceable(
150+
; CHECK: @strcmp
151+
132152
; int test_strcmp_2(const char *s) {
133153
; if (!strcmp(s, "aab"))
134154
; return 11;

0 commit comments

Comments
 (0)