Skip to content

Commit cbfcf90

Browse files
committed
[AggressiveInstCombine] Fold strcmp for short string literals with size 2
Fold strcmp for short string literals with size 2. Depends D155742. Differential Revision: https://reviews.llvm.org/D155743
1 parent 0c8d3db commit cbfcf90

File tree

2 files changed

+194
-41
lines changed

2 files changed

+194
-41
lines changed

llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ static bool foldSqrt(CallInst *Call, TargetTransformInfo &TTI,
906906
return false;
907907
}
908908

909-
/// Try to expand strcmp(P, "x") calls.
909+
/// Try to expand strcmp(P, string_literal) where string_literal size is 1 or 2
910910
static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
911911
Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
912912

@@ -921,16 +921,27 @@ static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
921921
Value *NonConstantP = nullptr;
922922
StringRef ConstantStr;
923923

924-
if (!HasStr1 && HasStr2 && Str2.size() == 1) {
924+
if (!HasStr1 && HasStr2) {
925925
NonConstantP = Str1P;
926926
ConstantStr = Str2;
927-
} else if (!HasStr2 && HasStr1 && Str1.size() == 1) {
927+
} else if (!HasStr2 && HasStr1) {
928928
NonConstantP = Str2P;
929929
ConstantStr = Str1;
930930
} else {
931931
return false;
932932
}
933933

934+
size_t ConstantStrSize = ConstantStr.size();
935+
936+
// Trivial cases are optimized during inst combine
937+
if (ConstantStrSize == 0) {
938+
return false;
939+
}
940+
941+
if (ConstantStrSize > 2) {
942+
return false;
943+
}
944+
934945
// Check if strcmp result is only used in a comparison with zero
935946
if (!isOnlyUsedInZeroComparison(CI))
936947
return false;
@@ -946,42 +957,76 @@ static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
946957
// v1 = P[1]
947958
// dst = phi(v0, v1)
948959
//
960+
// For strcmp(P, "xy") do the following transformation:
961+
//
962+
// (before)
963+
// dst = strcmp(P, "x")
964+
//
965+
// (after)
966+
// v0 = P[0] - 'x'
967+
// [if v0 == 0]
968+
// v1 = P[1] - 'y'
969+
// [if v1 == 0]
970+
// v2 = P[2]
971+
// dst = phi(v0, v1, v2)
972+
//
949973

950974
IRBuilder<> B(CI->getParent());
951975
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
952976

953977
Type *RetType = CI->getType();
954978

955-
B.SetInsertPoint(CI);
956-
BasicBlock *InitialBB = B.GetInsertBlock();
957-
Value *Str1FirstCharacterValue =
958-
B.CreateZExt(B.CreateLoad(B.getInt8Ty(), NonConstantP), RetType);
959-
Value *Str2FirstCharacterValue =
960-
ConstantInt::get(RetType, static_cast<unsigned char>(ConstantStr[0]));
961-
Value *FirstCharacterSub =
962-
B.CreateNSWSub(Str1FirstCharacterValue, Str2FirstCharacterValue);
963-
Value *IsFirstCharacterSubZero =
964-
B.CreateICmpEQ(FirstCharacterSub, ConstantInt::get(RetType, 0));
965-
Instruction *IsFirstCharacterSubZeroBBTerminator = SplitBlockAndInsertIfThen(
966-
IsFirstCharacterSubZero, CI, /*Unreachable*/ false,
967-
/*BranchWeights*/ nullptr, &DTU);
968-
969-
B.SetInsertPoint(IsFirstCharacterSubZeroBBTerminator);
970-
B.GetInsertBlock()->setName("strcmp_expand_sub_is_zero");
971-
BasicBlock *IsFirstCharacterSubZeroBB = B.GetInsertBlock();
972-
Value *Str1SecondCharacterValue = B.CreateZExt(
973-
B.CreateLoad(B.getInt8Ty(), B.CreateConstInBoundsGEP1_64(
974-
B.getInt8Ty(), NonConstantP, 1)),
975-
RetType);
979+
BasicBlock *InitialBB = CI->getParent();
980+
BasicBlock *JoinBlock = SplitBlock(InitialBB, CI, &DTU);
981+
JoinBlock->setName("strcmp_expand_sub_join");
976982

977983
B.SetInsertPoint(CI);
978-
B.GetInsertBlock()->setName("strcmp_expand_sub_join");
984+
PHINode *ResultPHI = B.CreatePHI(RetType, ConstantStrSize + 1);
985+
986+
B.SetInsertPoint(InitialBB);
987+
InitialBB->getTerminator()->eraseFromParent();
988+
989+
SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
990+
991+
size_t CharacterIndexToCheck = 0;
992+
for (; CharacterIndexToCheck < ConstantStrSize; ++CharacterIndexToCheck) {
993+
Value *StrCharacterValue = B.CreateZExt(
994+
B.CreateLoad(B.getInt8Ty(),
995+
B.CreateConstInBoundsGEP1_64(B.getInt8Ty(), NonConstantP,
996+
CharacterIndexToCheck)),
997+
RetType);
998+
Value *ConstantStrCharacterValue = ConstantInt::get(
999+
RetType,
1000+
static_cast<unsigned char>(ConstantStr[CharacterIndexToCheck]));
1001+
Value *CharacterSub =
1002+
B.CreateNSWSub(StrCharacterValue, ConstantStrCharacterValue);
1003+
Value *IsCharacterSubZero =
1004+
B.CreateICmpEQ(CharacterSub, ConstantInt::get(RetType, 0));
1005+
BasicBlock *IsCharacterSubZeroBB =
1006+
BasicBlock::Create(B.getContext(), "strcmp_expand_sub_is_zero",
1007+
InitialBB->getParent(), JoinBlock);
1008+
B.CreateCondBr(IsCharacterSubZero, IsCharacterSubZeroBB, JoinBlock);
1009+
1010+
ResultPHI->addIncoming(CharacterSub, B.GetInsertBlock());
1011+
DTUpdates.emplace_back(DominatorTree::Insert, B.GetInsertBlock(),
1012+
IsCharacterSubZeroBB);
1013+
1014+
B.SetInsertPoint(IsCharacterSubZeroBB);
1015+
DTUpdates.emplace_back(DominatorTree::Insert, IsCharacterSubZeroBB,
1016+
JoinBlock);
1017+
}
1018+
1019+
Value *StrLastCharacterValue = B.CreateZExt(
1020+
B.CreateLoad(B.getInt8Ty(),
1021+
B.CreateConstInBoundsGEP1_64(B.getInt8Ty(), NonConstantP,
1022+
CharacterIndexToCheck)),
1023+
RetType);
1024+
ResultPHI->addIncoming(StrLastCharacterValue, B.GetInsertBlock());
1025+
B.CreateBr(JoinBlock);
9791026

980-
PHINode *Result = B.CreatePHI(RetType, 2);
981-
Result->addIncoming(FirstCharacterSub, InitialBB);
982-
Result->addIncoming(Str1SecondCharacterValue, IsFirstCharacterSubZeroBB);
1027+
DTU.applyUpdates(DTUpdates);
9831028

984-
CI->replaceAllUsesWith(Result);
1029+
CI->replaceAllUsesWith(ResultPHI);
9851030
CI->eraseFromParent();
9861031

9871032
MadeCFGChange = true;

llvm/test/Transforms/AggressiveInstCombine/strcmp.ll

Lines changed: 120 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,26 @@ define i32 @expand_strcmp_s1_fail_3(ptr %C) {
209209

210210
define i1 @expand_strcmp_eq_s2(ptr %C) {
211211
; CHECK-LABEL: @expand_strcmp_eq_s2(
212-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
213-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
212+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
213+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
214+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
215+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
216+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
217+
; CHECK: strcmp_expand_sub_is_zero:
218+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
219+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
220+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
221+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
222+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
223+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
224+
; CHECK: strcmp_expand_sub_is_zero1:
225+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
226+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
227+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
228+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
229+
; CHECK: strcmp_expand_sub_join:
230+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
231+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP13]], 0
214232
; CHECK-NEXT: ret i1 [[CMP]]
215233
;
216234
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -220,8 +238,26 @@ define i1 @expand_strcmp_eq_s2(ptr %C) {
220238

221239
define i1 @expand_strcmp_ne_s2(ptr %C) {
222240
; CHECK-LABEL: @expand_strcmp_ne_s2(
223-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
224-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
241+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
242+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
243+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
244+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
245+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
246+
; CHECK: strcmp_expand_sub_is_zero:
247+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
248+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
249+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
250+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
251+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
252+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
253+
; CHECK: strcmp_expand_sub_is_zero1:
254+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
255+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
256+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
257+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
258+
; CHECK: strcmp_expand_sub_join:
259+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
260+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
225261
; CHECK-NEXT: ret i1 [[CMP]]
226262
;
227263
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -231,8 +267,26 @@ define i1 @expand_strcmp_ne_s2(ptr %C) {
231267

232268
define i1 @expand_strcmp_sgt_s2(ptr %C) {
233269
; CHECK-LABEL: @expand_strcmp_sgt_s2(
234-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
235-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
270+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
271+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
272+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
273+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
274+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
275+
; CHECK: strcmp_expand_sub_is_zero:
276+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
277+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
278+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
279+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
280+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
281+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
282+
; CHECK: strcmp_expand_sub_is_zero1:
283+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
284+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
285+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
286+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
287+
; CHECK: strcmp_expand_sub_join:
288+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
289+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP13]], 0
236290
; CHECK-NEXT: ret i1 [[CMP]]
237291
;
238292
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -242,8 +296,26 @@ define i1 @expand_strcmp_sgt_s2(ptr %C) {
242296

243297
define i1 @expand_strcmp_sge_s2(ptr %C) {
244298
; CHECK-LABEL: @expand_strcmp_sge_s2(
245-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
246-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CALL]], 0
299+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
300+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
301+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
302+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
303+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
304+
; CHECK: strcmp_expand_sub_is_zero:
305+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
306+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
307+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
308+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
309+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
310+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
311+
; CHECK: strcmp_expand_sub_is_zero1:
312+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
313+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
314+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
315+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
316+
; CHECK: strcmp_expand_sub_join:
317+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
318+
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP13]], 0
247319
; CHECK-NEXT: ret i1 [[CMP]]
248320
;
249321
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -253,8 +325,26 @@ define i1 @expand_strcmp_sge_s2(ptr %C) {
253325

254326
define i1 @expand_strcmp_slt_s2(ptr %C) {
255327
; CHECK-LABEL: @expand_strcmp_slt_s2(
256-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
257-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 0
328+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
329+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
330+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
331+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
332+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
333+
; CHECK: strcmp_expand_sub_is_zero:
334+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
335+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
336+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
337+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
338+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
339+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
340+
; CHECK: strcmp_expand_sub_is_zero1:
341+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
342+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
343+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
344+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
345+
; CHECK: strcmp_expand_sub_join:
346+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
347+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP13]], 0
258348
; CHECK-NEXT: ret i1 [[CMP]]
259349
;
260350
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -264,8 +354,26 @@ define i1 @expand_strcmp_slt_s2(ptr %C) {
264354

265355
define i1 @expand_strcmp_sle_s2(ptr %C) {
266356
; CHECK-LABEL: @expand_strcmp_sle_s2(
267-
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
268-
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CALL]], 0
357+
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
358+
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
359+
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
360+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
361+
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
362+
; CHECK: strcmp_expand_sub_is_zero:
363+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
364+
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
365+
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
366+
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
367+
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
368+
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
369+
; CHECK: strcmp_expand_sub_is_zero1:
370+
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
371+
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
372+
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
373+
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
374+
; CHECK: strcmp_expand_sub_join:
375+
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
376+
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP13]], 0
269377
; CHECK-NEXT: ret i1 [[CMP]]
270378
;
271379
%call = call i32 @strcmp(ptr %C, ptr @s2)

0 commit comments

Comments
 (0)