[llvm] cbfcf90 - [AggressiveInstCombine] Fold strcmp for short string literals with size 2
Maksim Kita via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 27 08:45:42 PDT 2023
Author: Maksim Kita
Date: 2023-07-27T18:45:21+03:00
New Revision: cbfcf90152de5392a36d0a0241eef25f5e159eef
URL: https://github.com/llvm/llvm-project/commit/cbfcf90152de5392a36d0a0241eef25f5e159eef
DIFF: https://github.com/llvm/llvm-project/commit/cbfcf90152de5392a36d0a0241eef25f5e159eef.diff
LOG: [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
Added:
Modified:
llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 34c8a380448e5a..4f2edde916b6c8 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -906,7 +906,7 @@ static bool foldSqrt(CallInst *Call, TargetTransformInfo &TTI,
return false;
}
-/// Try to expand strcmp(P, "x") calls.
+/// Try to expand strcmp(P, string_literal) where string_literal size is 1 or 2
static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
@@ -921,16 +921,27 @@ static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
Value *NonConstantP = nullptr;
StringRef ConstantStr;
- if (!HasStr1 && HasStr2 && Str2.size() == 1) {
+ if (!HasStr1 && HasStr2) {
NonConstantP = Str1P;
ConstantStr = Str2;
- } else if (!HasStr2 && HasStr1 && Str1.size() == 1) {
+ } else if (!HasStr2 && HasStr1) {
NonConstantP = Str2P;
ConstantStr = Str1;
} else {
return false;
}
+ size_t ConstantStrSize = ConstantStr.size();
+
+ // Trivial cases are optimized during inst combine
+ if (ConstantStrSize == 0) {
+ return false;
+ }
+
+ if (ConstantStrSize > 2) {
+ return false;
+ }
+
// Check if strcmp result is only used in a comparison with zero
if (!isOnlyUsedInZeroComparison(CI))
return false;
@@ -946,42 +957,76 @@ static bool expandStrcmp(CallInst *CI, DominatorTree &DT, bool &MadeCFGChange) {
// v1 = P[1]
// dst = phi(v0, v1)
//
+ // For strcmp(P, "xy") do the following transformation:
+ //
+ // (before)
+ // dst = strcmp(P, "x")
+ //
+ // (after)
+ // v0 = P[0] - 'x'
+ // [if v0 == 0]
+ // v1 = P[1] - 'y'
+ // [if v1 == 0]
+ // v2 = P[2]
+ // dst = phi(v0, v1, v2)
+ //
IRBuilder<> B(CI->getParent());
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
Type *RetType = CI->getType();
- B.SetInsertPoint(CI);
- BasicBlock *InitialBB = B.GetInsertBlock();
- Value *Str1FirstCharacterValue =
- B.CreateZExt(B.CreateLoad(B.getInt8Ty(), NonConstantP), RetType);
- Value *Str2FirstCharacterValue =
- ConstantInt::get(RetType, static_cast<unsigned char>(ConstantStr[0]));
- Value *FirstCharacterSub =
- B.CreateNSWSub(Str1FirstCharacterValue, Str2FirstCharacterValue);
- Value *IsFirstCharacterSubZero =
- B.CreateICmpEQ(FirstCharacterSub, ConstantInt::get(RetType, 0));
- Instruction *IsFirstCharacterSubZeroBBTerminator = SplitBlockAndInsertIfThen(
- IsFirstCharacterSubZero, CI, /*Unreachable*/ false,
- /*BranchWeights*/ nullptr, &DTU);
-
- B.SetInsertPoint(IsFirstCharacterSubZeroBBTerminator);
- B.GetInsertBlock()->setName("strcmp_expand_sub_is_zero");
- BasicBlock *IsFirstCharacterSubZeroBB = B.GetInsertBlock();
- Value *Str1SecondCharacterValue = B.CreateZExt(
- B.CreateLoad(B.getInt8Ty(), B.CreateConstInBoundsGEP1_64(
- B.getInt8Ty(), NonConstantP, 1)),
- RetType);
+ BasicBlock *InitialBB = CI->getParent();
+ BasicBlock *JoinBlock = SplitBlock(InitialBB, CI, &DTU);
+ JoinBlock->setName("strcmp_expand_sub_join");
B.SetInsertPoint(CI);
- B.GetInsertBlock()->setName("strcmp_expand_sub_join");
+ PHINode *ResultPHI = B.CreatePHI(RetType, ConstantStrSize + 1);
+
+ B.SetInsertPoint(InitialBB);
+ InitialBB->getTerminator()->eraseFromParent();
+
+ SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
+
+ size_t CharacterIndexToCheck = 0;
+ for (; CharacterIndexToCheck < ConstantStrSize; ++CharacterIndexToCheck) {
+ Value *StrCharacterValue = B.CreateZExt(
+ B.CreateLoad(B.getInt8Ty(),
+ B.CreateConstInBoundsGEP1_64(B.getInt8Ty(), NonConstantP,
+ CharacterIndexToCheck)),
+ RetType);
+ Value *ConstantStrCharacterValue = ConstantInt::get(
+ RetType,
+ static_cast<unsigned char>(ConstantStr[CharacterIndexToCheck]));
+ Value *CharacterSub =
+ B.CreateNSWSub(StrCharacterValue, ConstantStrCharacterValue);
+ Value *IsCharacterSubZero =
+ B.CreateICmpEQ(CharacterSub, ConstantInt::get(RetType, 0));
+ BasicBlock *IsCharacterSubZeroBB =
+ BasicBlock::Create(B.getContext(), "strcmp_expand_sub_is_zero",
+ InitialBB->getParent(), JoinBlock);
+ B.CreateCondBr(IsCharacterSubZero, IsCharacterSubZeroBB, JoinBlock);
+
+ ResultPHI->addIncoming(CharacterSub, B.GetInsertBlock());
+ DTUpdates.emplace_back(DominatorTree::Insert, B.GetInsertBlock(),
+ IsCharacterSubZeroBB);
+
+ B.SetInsertPoint(IsCharacterSubZeroBB);
+ DTUpdates.emplace_back(DominatorTree::Insert, IsCharacterSubZeroBB,
+ JoinBlock);
+ }
+
+ Value *StrLastCharacterValue = B.CreateZExt(
+ B.CreateLoad(B.getInt8Ty(),
+ B.CreateConstInBoundsGEP1_64(B.getInt8Ty(), NonConstantP,
+ CharacterIndexToCheck)),
+ RetType);
+ ResultPHI->addIncoming(StrLastCharacterValue, B.GetInsertBlock());
+ B.CreateBr(JoinBlock);
- PHINode *Result = B.CreatePHI(RetType, 2);
- Result->addIncoming(FirstCharacterSub, InitialBB);
- Result->addIncoming(Str1SecondCharacterValue, IsFirstCharacterSubZeroBB);
+ DTU.applyUpdates(DTUpdates);
- CI->replaceAllUsesWith(Result);
+ CI->replaceAllUsesWith(ResultPHI);
CI->eraseFromParent();
MadeCFGChange = true;
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll b/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
index b8ab551f052484..78d4ff573831b0 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
@@ -209,8 +209,26 @@ define i32 @expand_strcmp_s1_fail_3(ptr %C) {
define i1 @expand_strcmp_eq_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_eq_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -220,8 +238,26 @@ define i1 @expand_strcmp_eq_s2(ptr %C) {
define i1 @expand_strcmp_ne_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_ne_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -231,8 +267,26 @@ define i1 @expand_strcmp_ne_s2(ptr %C) {
define i1 @expand_strcmp_sgt_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_sgt_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -242,8 +296,26 @@ define i1 @expand_strcmp_sgt_s2(ptr %C) {
define i1 @expand_strcmp_sge_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_sge_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -253,8 +325,26 @@ define i1 @expand_strcmp_sge_s2(ptr %C) {
define i1 @expand_strcmp_slt_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_slt_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -264,8 +354,26 @@ define i1 @expand_strcmp_slt_s2(ptr %C) {
define i1 @expand_strcmp_sle_s2(ptr %C) {
; CHECK-LABEL: @expand_strcmp_sle_s2(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
-; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CALL]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
+; CHECK: strcmp_expand_sub_is_zero:
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
+; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_is_zero1:
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
+; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
+; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
+; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
+; CHECK: strcmp_expand_sub_join:
+; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP13]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%call = call i32 @strcmp(ptr %C, ptr @s2)
More information about the llvm-commits
mailing list