[llvm] a3fabc7 - Revert "[InstCombine] when calling conventions are compatible, don't convert the call to undef idiom"
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 12 13:57:34 PDT 2021
Author: Nikita Popov
Date: 2021-04-12T22:55:59+02:00
New Revision: a3fabc79ae9d7dd76545b2abc2a3bfb66c6d3175
URL: https://github.com/llvm/llvm-project/commit/a3fabc79ae9d7dd76545b2abc2a3bfb66c6d3175
DIFF: https://github.com/llvm/llvm-project/commit/a3fabc79ae9d7dd76545b2abc2a3bfb66c6d3175.diff
LOG: Revert "[InstCombine] when calling conventions are compatible, don't convert the call to undef idiom"
This reverts commit f4d682d6ce6c5b3a41a0acf297507c82f5c21eef.
This caused a significant compile-time regression:
https://llvm-compile-time-tracker.com/compare.php?from=4b7bad9eaea2233521a94f6b096aaa88dc584e23&to=f4d682d6ce6c5b3a41a0acf297507c82f5c21eef&stat=instructions
Possibly this is due to overeager parsing of target triples.
Added:
Modified:
llvm/include/llvm/Analysis/TargetLibraryInfo.h
llvm/lib/Analysis/TargetLibraryInfo.cpp
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
Removed:
llvm/test/Transforms/InstCombine/call-callconv-mismatch.ll
################################################################################
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index adc6363c5b71d..e913b918c4aae 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -192,11 +192,6 @@ class TargetLibraryInfoImpl {
/// vector functions.
void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
ElementCount &Scalable) const;
-
- /// Returns true if call site / callee has cdecl-compatible calling
- /// conventions.
- static bool isCallingConvCCompatible(CallBase *CI);
- static bool isCallingConvCCompatible(Function *Callee);
};
/// Provides information about what library functions are available for
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 14dcaa6964443..31cea8fe2a2a3 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -65,49 +65,6 @@ static bool hasBcmp(const Triple &TT) {
return TT.isOSFreeBSD() || TT.isOSSolaris();
}
-static bool isCallingConvCCompatible(CallingConv::ID CC, Triple TT,
- FunctionType *FuncTy) {
- switch (CC) {
- default:
- return false;
- case llvm::CallingConv::C:
- return true;
- case llvm::CallingConv::ARM_APCS:
- case llvm::CallingConv::ARM_AAPCS:
- case llvm::CallingConv::ARM_AAPCS_VFP: {
-
- // The iOS ABI diverges from the standard in some cases, so for now don't
- // try to simplify those calls.
- if (TT.isiOS())
- return false;
-
- if (!FuncTy->getReturnType()->isPointerTy() &&
- !FuncTy->getReturnType()->isIntegerTy() &&
- !FuncTy->getReturnType()->isVoidTy())
- return false;
-
- for (auto *Param : FuncTy->params()) {
- if (!Param->isPointerTy() && !Param->isIntegerTy())
- return false;
- }
- return true;
- }
- }
- return false;
-}
-
-bool TargetLibraryInfoImpl::isCallingConvCCompatible(CallBase *CI) {
- return ::isCallingConvCCompatible(CI->getCallingConv(),
- Triple(CI->getModule()->getTargetTriple()),
- CI->getFunctionType());
-}
-
-bool TargetLibraryInfoImpl::isCallingConvCCompatible(Function *F) {
- return ::isCallingConvCCompatible(F->getCallingConv(),
- Triple(F->getParent()->getTargetTriple()),
- F->getFunctionType());
-}
-
/// Initialize the set of available library functions based on the specified
/// target triple. This should be carefully written so that a missing target
/// triple gets a sane set of defaults.
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 615f10e1de7f3..78f45116063bc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2158,14 +2158,9 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
return &Call;
}
- // If the call and callee calling conventions don't match, and neither one
- // of the calling conventions is compatible with C calling convention
- // this call must be unreachable, as the call is undefined.
- if ((CalleeF->getCallingConv() != Call.getCallingConv() &&
- !(CalleeF->getCallingConv() == llvm::CallingConv::C &&
- TargetLibraryInfoImpl::isCallingConvCCompatible(&Call)) &&
- !(Call.getCallingConv() == llvm::CallingConv::C &&
- TargetLibraryInfoImpl::isCallingConvCCompatible(CalleeF))) &&
+ // If the call and callee calling conventions don't match, this call must
+ // be unreachable, as the call is undefined.
+ if (CalleeF->getCallingConv() != Call.getCallingConv() &&
// Only do this for calls to a function with a body. A prototype may
// not actually end up matching the implementation's calling conv for a
// variety of reasons (e.g. it may be written in assembly).
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 2e440511d6fde..c279d18043c02 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -56,6 +56,38 @@ static bool ignoreCallingConv(LibFunc Func) {
Func == LibFunc_llabs || Func == LibFunc_strlen;
}
+static bool isCallingConvCCompatible(CallInst *CI) {
+ switch(CI->getCallingConv()) {
+ default:
+ return false;
+ case llvm::CallingConv::C:
+ return true;
+ case llvm::CallingConv::ARM_APCS:
+ case llvm::CallingConv::ARM_AAPCS:
+ case llvm::CallingConv::ARM_AAPCS_VFP: {
+
+ // The iOS ABI diverges from the standard in some cases, so for now don't
+ // try to simplify those calls.
+ if (Triple(CI->getModule()->getTargetTriple()).isiOS())
+ return false;
+
+ auto *FuncTy = CI->getFunctionType();
+
+ if (!FuncTy->getReturnType()->isPointerTy() &&
+ !FuncTy->getReturnType()->isIntegerTy() &&
+ !FuncTy->getReturnType()->isVoidTy())
+ return false;
+
+ for (auto Param : FuncTy->params()) {
+ if (!Param->isPointerTy() && !Param->isIntegerTy())
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
/// Return true if it is only used in equality comparisons with With.
static bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
for (User *U : V->users()) {
@@ -2830,10 +2862,9 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
// Check for string/memory library functions.
if (TLI->getLibFunc(*Callee, Func) && TLI->has(Func)) {
// Make sure we never change the calling convention.
- assert(
- (ignoreCallingConv(Func) ||
- TargetLibraryInfoImpl::isCallingConvCCompatible(CI)) &&
- "Optimizing string/memory libcall would change the calling convention");
+ assert((ignoreCallingConv(Func) ||
+ isCallingConvCCompatible(CI)) &&
+ "Optimizing string/memory libcall would change the calling convention");
switch (Func) {
case LibFunc_strcat:
return optimizeStrCat(CI, Builder);
@@ -3017,7 +3048,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
LibFunc Func;
Function *Callee = CI->getCalledFunction();
- bool IsCallingConvC = TargetLibraryInfoImpl::isCallingConvCCompatible(CI);
+ bool isCallingConvC = isCallingConvCCompatible(CI);
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
@@ -3035,7 +3066,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
// First, check for intrinsics.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
- if (!IsCallingConvC)
+ if (!isCallingConvC)
return nullptr;
// The FP intrinsics have corresponding constrained versions so we don't
// need to check for the StrictFP attribute here.
@@ -3088,7 +3119,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
// Then check for known library functions.
if (TLI->getLibFunc(*Callee, Func) && TLI->has(Func)) {
// We never change the calling convention.
- if (!ignoreCallingConv(Func) && !IsCallingConvC)
+ if (!ignoreCallingConv(Func) && !isCallingConvC)
return nullptr;
if (Value *V = optimizeStringMemoryLibCall(CI, Builder))
return V;
@@ -3472,7 +3503,7 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI,
LibFunc Func;
Function *Callee = CI->getCalledFunction();
- bool IsCallingConvC = TargetLibraryInfoImpl::isCallingConvCCompatible(CI);
+ bool isCallingConvC = isCallingConvCCompatible(CI);
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
@@ -3486,7 +3517,7 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI,
return nullptr;
// We never change the calling convention.
- if (!ignoreCallingConv(Func) && !IsCallingConvC)
+ if (!ignoreCallingConv(Func) && !isCallingConvC)
return nullptr;
switch (Func) {
diff --git a/llvm/test/Transforms/InstCombine/call-callconv-mismatch.ll b/llvm/test/Transforms/InstCombine/call-callconv-mismatch.ll
deleted file mode 100644
index de1110d952ba4..0000000000000
--- a/llvm/test/Transforms/InstCombine/call-callconv-mismatch.ll
+++ /dev/null
@@ -1,22 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -S | FileCheck %s
-; Verify that a cdecl-compatible calling convention does not trigger emitting
-; unreachable idom `store i1 true, i1* undef`.
-
-define arm_aapcs_vfpcc i8 @bar(i8* %0) {
-; CHECK-LABEL: @bar(
-; CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[TMP0:%.*]], align 1
-; CHECK-NEXT: ret i8 [[TMP2]]
-;
- %2 = load i8, i8* %0, align 1
- ret i8 %2
-}
-
-define dso_local arm_aapcs_vfpcc i8 @foo(i8* %0) {
-; CHECK-LABEL: @foo(
-; CHECK-NEXT: [[TMP2:%.*]] = call i8 @bar(i8* [[TMP0:%.*]])
-; CHECK-NEXT: ret i8 [[TMP2]]
-;
- %2 = call i8 @bar(i8* %0)
- ret i8 %2
-}
More information about the llvm-commits
mailing list