[llvm] 0b779b0 - Revert "[AggressiveInstCombine] Fold strcmp for short string literals"

Alexander Kornienko via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 8 13:53:49 PDT 2023


Author: Alexander Kornienko
Date: 2023-08-08T22:53:45+02:00
New Revision: 0b779b0daa4cfb7d99d10232890d98b43ff56ef0

URL: https://github.com/llvm/llvm-project/commit/0b779b0daa4cfb7d99d10232890d98b43ff56ef0
DIFF: https://github.com/llvm/llvm-project/commit/0b779b0daa4cfb7d99d10232890d98b43ff56ef0.diff

LOG: Revert "[AggressiveInstCombine] Fold strcmp for short string literals"

This reverts commit 5dde755188e34c0ba5304365612904476c8adfda,
cbfcf90152de5392a36d0a0241eef25f5e159eef and
8981520b19f2d2fe3d2bc80cf26318ee6b5b7473 due to a miscompile introduced in
8981520b19f2d2fe3d2bc80cf26318ee6b5b7473 (see
https://reviews.llvm.org/D154725#4568845 for details)

Differential Revision: https://reviews.llvm.org/D157430

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ValueTracking.h
    llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
    llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/test/Transforms/AggressiveInstCombine/strcmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 824b1375a852d9..3521fa8be3b691 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -124,10 +124,6 @@ bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL,
                             const DominatorTree *DT = nullptr,
                             bool UseInstrInfo = true);
 
-/// Return true if the given instruction is only used in zero comparison
-bool isOnlyUsedInZeroComparison(const Instruction *CxtI);
-
-/// Return true if the given instruction is only used in zero equality comparison
 bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI);
 
 /// Return true if the given value is known to be non-zero when defined. For

diff  --git a/llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h b/llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h
index 3568417510f107..2d76546316fafb 100644
--- a/llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h
+++ b/llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h
@@ -8,7 +8,7 @@
 /// \file
 ///
 /// AggressiveInstCombiner - Combine expression patterns to form expressions
-/// with fewer, simple instructions.
+/// with fewer, simple instructions. This pass does not modify the CFG.
 ///
 //===----------------------------------------------------------------------===//
 

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 8bae935bc9543f..652b1e8b653a41 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -261,13 +261,6 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
   return KnownBits::haveNoCommonBitsSet(LHSKnown, RHSKnown);
 }
 
-bool llvm::isOnlyUsedInZeroComparison(const Instruction *I) {
-  return !I->user_empty() && all_of(I->users(), [](const User *U) {
-    ICmpInst::Predicate P;
-    return match(U, m_ICmp(P, m_Value(), m_Zero()));
-  });
-}
-
 bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
   return !I->user_empty() && all_of(I->users(), [](const User *U) {
     ICmpInst::Predicate P;

diff  --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 341107236d7911..f692b1dd08a602 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -19,7 +19,6 @@
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
@@ -29,7 +28,6 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/PatternMatch.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/BuildLibCalls.h"
 #include "llvm/Transforms/Utils/Local.h"
 
@@ -398,6 +396,54 @@ static bool tryToFPToSat(Instruction &I, TargetTransformInfo &TTI) {
   return true;
 }
 
+/// Try to replace a mathlib call to sqrt with the LLVM intrinsic. This avoids
+/// pessimistic codegen that has to account for setting errno and can enable
+/// vectorization.
+static bool foldSqrt(Instruction &I, TargetTransformInfo &TTI,
+                     TargetLibraryInfo &TLI, AssumptionCache &AC,
+                     DominatorTree &DT) {
+  // Match a call to sqrt mathlib function.
+  auto *Call = dyn_cast<CallInst>(&I);
+  if (!Call)
+    return false;
+
+  Module *M = Call->getModule();
+  LibFunc Func;
+  if (!TLI.getLibFunc(*Call, Func) || !isLibFuncEmittable(M, &TLI, Func))
+    return false;
+
+  if (Func != LibFunc_sqrt && Func != LibFunc_sqrtf && Func != LibFunc_sqrtl)
+    return false;
+
+  // If (1) this is a sqrt libcall, (2) we can assume that NAN is not created
+  // (because NNAN or the operand arg must not be less than -0.0) and (2) we
+  // would not end up lowering to a libcall anyway (which could change the value
+  // of errno), then:
+  // (1) errno won't be set.
+  // (2) it is safe to convert this to an intrinsic call.
+  Type *Ty = Call->getType();
+  Value *Arg = Call->getArgOperand(0);
+  if (TTI.haveFastSqrt(Ty) &&
+      (Call->hasNoNaNs() ||
+       cannotBeOrderedLessThanZero(Arg, M->getDataLayout(), &TLI, 0, &AC, &I,
+                                   &DT))) {
+    IRBuilder<> Builder(&I);
+    IRBuilderBase::FastMathFlagGuard Guard(Builder);
+    Builder.setFastMathFlags(Call->getFastMathFlags());
+
+    Function *Sqrt = Intrinsic::getDeclaration(M, Intrinsic::sqrt, Ty);
+    Value *NewSqrt = Builder.CreateCall(Sqrt, Arg, "sqrt");
+    I.replaceAllUsesWith(NewSqrt);
+
+    // Explicitly erase the old call because a call with side effects is not
+    // trivially dead.
+    I.eraseFromParent();
+    return true;
+  }
+
+  return false;
+}
+
 // Check if this array of constants represents a cttz table.
 // Iterate over the elements from \p Table by trying to find/match all
 // the numbers from 0 to \p InputBits that should represent cttz results.
@@ -869,199 +915,13 @@ static bool foldPatternedLoads(Instruction &I, const DataLayout &DL) {
   return true;
 }
 
-/// Try to replace a mathlib call to sqrt with the LLVM intrinsic. This avoids
-/// pessimistic codegen that has to account for setting errno and can enable
-/// vectorization.
-static bool foldSqrt(CallInst *Call, TargetTransformInfo &TTI,
-                     TargetLibraryInfo &TLI, AssumptionCache &AC,
-                     DominatorTree &DT) {
-  Module *M = Call->getModule();
-
-  // If (1) this is a sqrt libcall, (2) we can assume that NAN is not created
-  // (because NNAN or the operand arg must not be less than -0.0) and (2) we
-  // would not end up lowering to a libcall anyway (which could change the value
-  // of errno), then:
-  // (1) errno won't be set.
-  // (2) it is safe to convert this to an intrinsic call.
-  Type *Ty = Call->getType();
-  Value *Arg = Call->getArgOperand(0);
-  if (TTI.haveFastSqrt(Ty) &&
-      (Call->hasNoNaNs() ||
-       cannotBeOrderedLessThanZero(Arg, M->getDataLayout(), &TLI, 0, &AC, Call,
-                                   &DT))) {
-    IRBuilder<> Builder(Call);
-    IRBuilderBase::FastMathFlagGuard Guard(Builder);
-    Builder.setFastMathFlags(Call->getFastMathFlags());
-
-    Function *Sqrt = Intrinsic::getDeclaration(M, Intrinsic::sqrt, Ty);
-    Value *NewSqrt = Builder.CreateCall(Sqrt, Arg, "sqrt");
-    Call->replaceAllUsesWith(NewSqrt);
-
-    // Explicitly erase the old call because a call with side effects is not
-    // trivially dead.
-    Call->eraseFromParent();
-    return true;
-  }
-
-  return false;
-}
-
-/// 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);
-
-  // Trivial cases are optimized during inst combine
-  if (Str1P == Str2P)
-    return false;
-
-  StringRef Str1, Str2;
-  bool HasStr1 = getConstantStringInfo(Str1P, Str1);
-  bool HasStr2 = getConstantStringInfo(Str2P, Str2);
-
-  Value *NonConstantP = nullptr;
-  StringRef ConstantStr;
-
-  if (!HasStr1 && HasStr2) {
-    NonConstantP = Str1P;
-    ConstantStr = Str2;
-  } 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 || ConstantStrSize > 2)
-    return false;
-
-  // Check if strcmp result is only used in a comparison with zero
-  if (!isOnlyUsedInZeroComparison(CI))
-    return false;
-
-  // For strcmp(P, "x") do the following transformation:
-  //
-  // (before)
-  // dst = strcmp(P, "x")
-  //
-  // (after)
-  // v0 = P[0] - 'x'
-  // [if v0 == 0]
-  //   v1 = P[1]
-  // dst = phi(v0, v1)
-  //
-  // For strcmp(P, "xy") do the following transformation:
-  //
-  // (before)
-  // dst = strcmp(P, "xy")
-  //
-  // (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();
-
-  BasicBlock *InitialBB = CI->getParent();
-  BasicBlock *JoinBlock = SplitBlock(InitialBB, CI, &DTU);
-  JoinBlock->setName("strcmp_expand_sub_join");
-
-  B.SetInsertPoint(CI);
-  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 *CharacterSubIsZero =
-        B.CreateICmpEQ(CharacterSub, ConstantInt::get(RetType, 0));
-    BasicBlock *CharacterSubIsZeroBB =
-        BasicBlock::Create(B.getContext(), "strcmp_expand_sub_is_zero",
-                           InitialBB->getParent(), JoinBlock);
-    B.CreateCondBr(CharacterSubIsZero, CharacterSubIsZeroBB, JoinBlock);
-
-    ResultPHI->addIncoming(CharacterSub, B.GetInsertBlock());
-    DTUpdates.emplace_back(DominatorTree::Insert, B.GetInsertBlock(),
-                           CharacterSubIsZeroBB);
-
-    B.SetInsertPoint(CharacterSubIsZeroBB);
-    DTUpdates.emplace_back(DominatorTree::Insert, CharacterSubIsZeroBB,
-                           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);
-
-  DTU.applyUpdates(DTUpdates);
-
-  CI->replaceAllUsesWith(ResultPHI);
-  CI->eraseFromParent();
-
-  MadeCFGChange = true;
-
-  return true;
-}
-
-static bool foldLibraryCalls(Instruction &I, TargetTransformInfo &TTI,
-                             TargetLibraryInfo &TLI, DominatorTree &DT,
-                             AssumptionCache &AC, bool &MadeCFGChange) {
-  CallInst *CI = dyn_cast<CallInst>(&I);
-  if (!CI)
-    return false;
-
-  LibFunc Func;
-  Module *M = I.getModule();
-  if (!TLI.getLibFunc(*CI, Func) || !isLibFuncEmittable(M, &TLI, Func))
-    return false;
-
-  switch (Func) {
-  case LibFunc_sqrt:
-  case LibFunc_sqrtf:
-  case LibFunc_sqrtl:
-    return foldSqrt(CI, TTI, TLI, AC, DT);
-  case LibFunc_strcmp:
-    return expandStrcmp(CI, DT, MadeCFGChange);
-  default:
-    break;
-  }
-
-  return false;
-}
-
 /// This is the entry point for folds that could be implemented in regular
 /// InstCombine, but they are separated because they are not expected to
 /// occur frequently and/or have more than a constant-length pattern match.
 static bool foldUnusualPatterns(Function &F, DominatorTree &DT,
                                 TargetTransformInfo &TTI,
                                 TargetLibraryInfo &TLI, AliasAnalysis &AA,
-                                AssumptionCache &AC, bool &MadeCFGChange) {
+                                AssumptionCache &AC) {
   bool MadeChange = false;
   for (BasicBlock &BB : F) {
     // Ignore unreachable basic blocks.
@@ -1086,7 +946,7 @@ static bool foldUnusualPatterns(Function &F, DominatorTree &DT,
       // NOTE: This function introduces erasing of the instruction `I`, so it
       // needs to be called at the end of this sequence, otherwise we may make
       // bugs.
-      MadeChange |= foldLibraryCalls(I, TTI, TLI, DT, AC, MadeCFGChange);
+      MadeChange |= foldSqrt(I, TTI, TLI, AC, DT);
     }
   }
 
@@ -1102,12 +962,12 @@ static bool foldUnusualPatterns(Function &F, DominatorTree &DT,
 /// handled in the callers of this function.
 static bool runImpl(Function &F, AssumptionCache &AC, TargetTransformInfo &TTI,
                     TargetLibraryInfo &TLI, DominatorTree &DT,
-                    AliasAnalysis &AA, bool &ChangedCFG) {
+                    AliasAnalysis &AA) {
   bool MadeChange = false;
   const DataLayout &DL = F.getParent()->getDataLayout();
   TruncInstCombine TIC(AC, TLI, DL, DT);
   MadeChange |= TIC.run(F);
-  MadeChange |= foldUnusualPatterns(F, DT, TTI, TLI, AA, AC, ChangedCFG);
+  MadeChange |= foldUnusualPatterns(F, DT, TTI, TLI, AA, AC);
   return MadeChange;
 }
 
@@ -1118,21 +978,12 @@ PreservedAnalyses AggressiveInstCombinePass::run(Function &F,
   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
   auto &TTI = AM.getResult<TargetIRAnalysis>(F);
   auto &AA = AM.getResult<AAManager>(F);
-
-  bool MadeCFGChange = false;
-
-  if (!runImpl(F, AC, TTI, TLI, DT, AA, MadeCFGChange)) {
+  if (!runImpl(F, AC, TTI, TLI, DT, AA)) {
     // No changes, all analyses are preserved.
     return PreservedAnalyses::all();
   }
-
   // Mark all the analyses that instcombine updates as preserved.
   PreservedAnalyses PA;
-
-  if (MadeCFGChange)
-    PA.preserve<DominatorTreeAnalysis>();
-  else
-    PA.preserveSet<CFGAnalyses>();
-
+  PA.preserveSet<CFGAnalyses>();
   return PA;
 }

diff  --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 4fb167b738cc2a..d7f45d637e2445 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -227,9 +227,21 @@ static Value *convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr,
   return ConstantInt::get(RetTy, Result);
 }
 
+static bool isOnlyUsedInComparisonWithZero(Value *V) {
+  for (User *U : V->users()) {
+    if (ICmpInst *IC = dyn_cast<ICmpInst>(U))
+      if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
+        if (C->isNullValue())
+          continue;
+    // Unknown instruction.
+    return false;
+  }
+  return true;
+}
+
 static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len,
                                  const DataLayout &DL) {
-  if (!isOnlyUsedInZeroComparison(CI))
+  if (!isOnlyUsedInComparisonWithZero(CI))
     return false;
 
   if (!isDereferenceableAndAlignedPointer(Str, Align(1), APInt(64, Len), DL))

diff  --git a/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll b/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
index 78d4ff573831b0..99dd450e6f44e6 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/strcmp.ll
@@ -24,19 +24,8 @@ define i1 @expand_strcmp_s0(ptr %C) {
 
 define i1 @expand_strcmp_eq_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_eq_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -46,19 +35,8 @@ define i1 @expand_strcmp_eq_s1(ptr %C) {
 
 define i1 @expand_strcmp_eq_s1_commuted(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_eq_s1_commuted(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr @s1, ptr [[C:%.*]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr @s1, ptr %C)
@@ -68,19 +46,8 @@ define i1 @expand_strcmp_eq_s1_commuted(ptr %C) {
 
 define i1 @expand_strcmp_ne_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_ne_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -90,19 +57,8 @@ define i1 @expand_strcmp_ne_s1(ptr %C) {
 
 define i1 @expand_strcmp_sgt_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sgt_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -112,19 +68,8 @@ define i1 @expand_strcmp_sgt_s1(ptr %C) {
 
 define i1 @expand_strcmp_sge_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sge_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -134,19 +79,8 @@ define i1 @expand_strcmp_sge_s1(ptr %C) {
 
 define i1 @expand_strcmp_slt_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_slt_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -156,19 +90,8 @@ define i1 @expand_strcmp_slt_s1(ptr %C) {
 
 define i1 @expand_strcmp_sle_s1(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sle_s1(
-; 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:    br label [[STRCMP_EXPAND_SUB_JOIN]]
-; CHECK:       strcmp_expand_sub_join:
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP8]], 0
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s1)
@@ -209,26 +132,8 @@ 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:    [[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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -238,26 +143,8 @@ define i1 @expand_strcmp_eq_s2(ptr %C) {
 
 define i1 @expand_strcmp_ne_s2(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_ne_s2(
-; 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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -267,26 +154,8 @@ define i1 @expand_strcmp_ne_s2(ptr %C) {
 
 define i1 @expand_strcmp_sgt_s2(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sgt_s2(
-; 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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -296,26 +165,8 @@ define i1 @expand_strcmp_sgt_s2(ptr %C) {
 
 define i1 @expand_strcmp_sge_s2(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sge_s2(
-; 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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -325,26 +176,8 @@ define i1 @expand_strcmp_sge_s2(ptr %C) {
 
 define i1 @expand_strcmp_slt_s2(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_slt_s2(
-; 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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)
@@ -354,26 +187,8 @@ define i1 @expand_strcmp_slt_s2(ptr %C) {
 
 define i1 @expand_strcmp_sle_s2(ptr %C) {
 ; CHECK-LABEL: @expand_strcmp_sle_s2(
-; 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:    [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s2)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[CALL]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %call = call i32 @strcmp(ptr %C, ptr @s2)


        


More information about the llvm-commits mailing list