mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
Turn MipsOptimizeMathLibCalls into a target-independent scalar transform
...so that it can be used for z too. Most of the code is the same. The only real change is to use TargetTransformInfo to test when a sqrt instruction is available. The pass is opt-in because at the moment it only handles sqrt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189097 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -74,6 +74,9 @@ void LLVMAddLoopUnswitchPass(LLVMPassManagerRef PM);
|
|||||||
/** See llvm::createMemCpyOptPass function. */
|
/** See llvm::createMemCpyOptPass function. */
|
||||||
void LLVMAddMemCpyOptPass(LLVMPassManagerRef PM);
|
void LLVMAddMemCpyOptPass(LLVMPassManagerRef PM);
|
||||||
|
|
||||||
|
/** See llvm::createPartiallyInlineLibCallsPass function. */
|
||||||
|
void LLVMAddPartiallyInlineLibCallsPass(LLVMPassManagerRef PM);
|
||||||
|
|
||||||
/** See llvm::createPromoteMemoryToRegisterPass function. */
|
/** See llvm::createPromoteMemoryToRegisterPass function. */
|
||||||
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
|
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
|
||||||
|
|
||||||
|
@@ -262,6 +262,10 @@ public:
|
|||||||
/// getPopcntSupport - Return hardware support for population count.
|
/// getPopcntSupport - Return hardware support for population count.
|
||||||
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
|
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
|
||||||
|
|
||||||
|
/// haveFastSqrt -- Return true if the hardware has a fast square-root
|
||||||
|
/// instruction.
|
||||||
|
virtual bool haveFastSqrt(Type *Ty) const;
|
||||||
|
|
||||||
/// getIntImmCost - Return the expected cost of materializing the given
|
/// getIntImmCost - Return the expected cost of materializing the given
|
||||||
/// integer immediate of the specified type.
|
/// integer immediate of the specified type.
|
||||||
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
|
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
|
||||||
|
@@ -205,6 +205,7 @@ void initializeObjCARCContractPass(PassRegistry&);
|
|||||||
void initializeObjCARCOptPass(PassRegistry&);
|
void initializeObjCARCOptPass(PassRegistry&);
|
||||||
void initializeOptimalEdgeProfilerPass(PassRegistry&);
|
void initializeOptimalEdgeProfilerPass(PassRegistry&);
|
||||||
void initializeOptimizePHIsPass(PassRegistry&);
|
void initializeOptimizePHIsPass(PassRegistry&);
|
||||||
|
void initializePartiallyInlineLibCallsPass(PassRegistry&);
|
||||||
void initializePEIPass(PassRegistry&);
|
void initializePEIPass(PassRegistry&);
|
||||||
void initializePHIEliminationPass(PassRegistry&);
|
void initializePHIEliminationPass(PassRegistry&);
|
||||||
void initializePartialInlinerPass(PassRegistry&);
|
void initializePartialInlinerPass(PassRegistry&);
|
||||||
|
@@ -163,6 +163,7 @@ namespace {
|
|||||||
(void) llvm::createLoopVectorizePass();
|
(void) llvm::createLoopVectorizePass();
|
||||||
(void) llvm::createSLPVectorizerPass();
|
(void) llvm::createSLPVectorizerPass();
|
||||||
(void) llvm::createBBVectorizePass();
|
(void) llvm::createBBVectorizePass();
|
||||||
|
(void) llvm::createPartiallyInlineLibCallsPass();
|
||||||
|
|
||||||
(void)new llvm::IntervalPartition();
|
(void)new llvm::IntervalPartition();
|
||||||
(void)new llvm::FindUsedTypes();
|
(void)new llvm::FindUsedTypes();
|
||||||
|
@@ -354,6 +354,13 @@ extern char &InstructionSimplifierID;
|
|||||||
FunctionPass *createLowerExpectIntrinsicPass();
|
FunctionPass *createLowerExpectIntrinsicPass();
|
||||||
|
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// PartiallyInlineLibCalls - Tries to inline the fast path of library
|
||||||
|
// calls such as sqrt.
|
||||||
|
//
|
||||||
|
FunctionPass *createPartiallyInlineLibCallsPass();
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -145,6 +145,10 @@ TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
|
|||||||
return PrevTTI->getPopcntSupport(IntTyWidthInBit);
|
return PrevTTI->getPopcntSupport(IntTyWidthInBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
|
||||||
|
return PrevTTI->haveFastSqrt(Ty);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const {
|
unsigned TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||||
return PrevTTI->getIntImmCost(Imm, Ty);
|
return PrevTTI->getIntImmCost(Imm, Ty);
|
||||||
}
|
}
|
||||||
@@ -505,6 +509,10 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
|
|||||||
return PSK_Software;
|
return PSK_Software;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool haveFastSqrt(Type *Ty) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned getIntImmCost(const APInt &Imm, Type *Ty) const {
|
unsigned getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -83,6 +83,7 @@ public:
|
|||||||
virtual unsigned getJumpBufAlignment() const;
|
virtual unsigned getJumpBufAlignment() const;
|
||||||
virtual unsigned getJumpBufSize() const;
|
virtual unsigned getJumpBufSize() const;
|
||||||
virtual bool shouldBuildLookupTables() const;
|
virtual bool shouldBuildLookupTables() const;
|
||||||
|
virtual bool haveFastSqrt(Type *Ty) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -182,6 +183,12 @@ bool BasicTTI::shouldBuildLookupTables() const {
|
|||||||
TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other));
|
TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BasicTTI::haveFastSqrt(Type *Ty) const {
|
||||||
|
const TargetLoweringBase *TLI = getTLI();
|
||||||
|
EVT VT = TLI->getValueType(Ty);
|
||||||
|
return TLI->isTypeLegal(VT) && TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Calls used by the vectorizers.
|
// Calls used by the vectorizers.
|
||||||
|
@@ -35,7 +35,6 @@ add_llvm_target(MipsCodeGen
|
|||||||
MipsMachineFunction.cpp
|
MipsMachineFunction.cpp
|
||||||
MipsModuleISelDAGToDAG.cpp
|
MipsModuleISelDAGToDAG.cpp
|
||||||
MipsOs16.cpp
|
MipsOs16.cpp
|
||||||
MipsOptimizeMathLibCalls.cpp
|
|
||||||
MipsRegisterInfo.cpp
|
MipsRegisterInfo.cpp
|
||||||
MipsSEFrameLowering.cpp
|
MipsSEFrameLowering.cpp
|
||||||
MipsSEInstrInfo.cpp
|
MipsSEInstrInfo.cpp
|
||||||
|
@@ -28,7 +28,6 @@ namespace llvm {
|
|||||||
FunctionPass *createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
FunctionPass *createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||||
JITCodeEmitter &JCE);
|
JITCodeEmitter &JCE);
|
||||||
FunctionPass *createMipsConstantIslandPass(MipsTargetMachine &tm);
|
FunctionPass *createMipsConstantIslandPass(MipsTargetMachine &tm);
|
||||||
FunctionPass *createMipsOptimizeMathLibCalls(MipsTargetMachine &TM);
|
|
||||||
} // end namespace llvm;
|
} // end namespace llvm;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
|
#include "llvm/Transforms/Scalar.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ void MipsPassConfig::addIRPasses() {
|
|||||||
addPass(createMipsOs16(getMipsTargetMachine()));
|
addPass(createMipsOs16(getMipsTargetMachine()));
|
||||||
if (getMipsSubtarget().inMips16HardFloat())
|
if (getMipsSubtarget().inMips16HardFloat())
|
||||||
addPass(createMips16HardFloat(getMipsTargetMachine()));
|
addPass(createMips16HardFloat(getMipsTargetMachine()));
|
||||||
addPass(createMipsOptimizeMathLibCalls(getMipsTargetMachine()));
|
addPass(createPartiallyInlineLibCallsPass());
|
||||||
}
|
}
|
||||||
// Install an instruction selector pass using
|
// Install an instruction selector pass using
|
||||||
// the ISelDag to gen Mips code.
|
// the ISelDag to gen Mips code.
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "SystemZTargetMachine.h"
|
#include "SystemZTargetMachine.h"
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
|
#include "llvm/Transforms/Scalar.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -47,12 +48,18 @@ public:
|
|||||||
return getTM<SystemZTargetMachine>();
|
return getTM<SystemZTargetMachine>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void addIRPasses() LLVM_OVERRIDE;
|
||||||
virtual bool addInstSelector() LLVM_OVERRIDE;
|
virtual bool addInstSelector() LLVM_OVERRIDE;
|
||||||
virtual bool addPreSched2() LLVM_OVERRIDE;
|
virtual bool addPreSched2() LLVM_OVERRIDE;
|
||||||
virtual bool addPreEmitPass() LLVM_OVERRIDE;
|
virtual bool addPreEmitPass() LLVM_OVERRIDE;
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
void SystemZPassConfig::addIRPasses() {
|
||||||
|
TargetPassConfig::addIRPasses();
|
||||||
|
addPass(createPartiallyInlineLibCallsPass());
|
||||||
|
}
|
||||||
|
|
||||||
bool SystemZPassConfig::addInstSelector() {
|
bool SystemZPassConfig::addInstSelector() {
|
||||||
addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));
|
addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));
|
||||||
return false;
|
return false;
|
||||||
|
@@ -21,6 +21,7 @@ add_llvm_library(LLVMScalarOpts
|
|||||||
LoopUnswitch.cpp
|
LoopUnswitch.cpp
|
||||||
LowerAtomic.cpp
|
LowerAtomic.cpp
|
||||||
MemCpyOptimizer.cpp
|
MemCpyOptimizer.cpp
|
||||||
|
PartiallyInlineLibCalls.cpp
|
||||||
Reassociate.cpp
|
Reassociate.cpp
|
||||||
Reg2Mem.cpp
|
Reg2Mem.cpp
|
||||||
SCCP.cpp
|
SCCP.cpp
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
//===---- MipsOptimizeMathLibCalls.cpp - Optimize math lib calls. ----===//
|
//===--- PartiallyInlineLibCalls.cpp - Partially inline libcalls ----------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@@ -7,76 +7,60 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This pass does an IR transformation which enables the backend to emit native
|
// This pass tries to partially inline the fast path of well-known library
|
||||||
// math instructions.
|
// functions, such as using square-root instructions for cases where sqrt()
|
||||||
|
// does not need to set errno.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "MipsTargetMachine.h"
|
#define DEBUG_TYPE "partially-inline-libcalls"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Target/TargetLibraryInfo.h"
|
#include "llvm/Target/TargetLibraryInfo.h"
|
||||||
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static cl::opt<bool> DisableOpt("disable-mips-math-optimization",
|
|
||||||
cl::init(false),
|
|
||||||
cl::desc("MIPS: Disable math lib call "
|
|
||||||
"optimization."), cl::Hidden);
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class MipsOptimizeMathLibCalls : public FunctionPass {
|
class PartiallyInlineLibCalls : public FunctionPass {
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
MipsOptimizeMathLibCalls(MipsTargetMachine &TM_) :
|
PartiallyInlineLibCalls() :
|
||||||
FunctionPass(ID), TM(TM_) {}
|
FunctionPass(ID) {
|
||||||
|
initializePartiallyInlineLibCallsPass(*PassRegistry::getPassRegistry());
|
||||||
virtual const char *getPassName() const {
|
|
||||||
return "MIPS: Optimize calls to math library functions.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &F);
|
virtual bool runOnFunction(Function &F);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Optimize calls to sqrt.
|
/// Optimize calls to sqrt.
|
||||||
bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
|
bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
|
||||||
BasicBlock &CurrBB,
|
BasicBlock &CurrBB, Function::iterator &BB);
|
||||||
Function::iterator &BB);
|
|
||||||
|
|
||||||
const TargetMachine &TM;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
char MipsOptimizeMathLibCalls::ID = 0;
|
char PartiallyInlineLibCalls::ID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPass *llvm::createMipsOptimizeMathLibCalls(MipsTargetMachine &TM) {
|
INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls",
|
||||||
return new MipsOptimizeMathLibCalls(TM);
|
"Partially inline calls to library functions", false, false)
|
||||||
}
|
|
||||||
|
|
||||||
void MipsOptimizeMathLibCalls::getAnalysisUsage(AnalysisUsage &AU) const {
|
void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<TargetLibraryInfo>();
|
AU.addRequired<TargetLibraryInfo>();
|
||||||
|
AU.addRequired<TargetTransformInfo>();
|
||||||
FunctionPass::getAnalysisUsage(AU);
|
FunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MipsOptimizeMathLibCalls::runOnFunction(Function &F) {
|
bool PartiallyInlineLibCalls::runOnFunction(Function &F) {
|
||||||
if (DisableOpt)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
|
|
||||||
|
|
||||||
if (Subtarget.inMips16Mode())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
Function::iterator CurrBB;
|
Function::iterator CurrBB;
|
||||||
const TargetLibraryInfo *LibInfo = &getAnalysis<TargetLibraryInfo>();
|
TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
|
||||||
|
const TargetTransformInfo *TTI = &getAnalysis<TargetTransformInfo>();
|
||||||
for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
|
for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
|
||||||
CurrBB = BB++;
|
CurrBB = BB++;
|
||||||
|
|
||||||
@@ -88,25 +72,18 @@ bool MipsOptimizeMathLibCalls::runOnFunction(Function &F) {
|
|||||||
if (!Call || !(CalledFunc = Call->getCalledFunction()))
|
if (!Call || !(CalledFunc = Call->getCalledFunction()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LibFunc::Func LibFunc;
|
|
||||||
Attribute A = CalledFunc->getAttributes()
|
|
||||||
.getAttribute(AttributeSet::FunctionIndex, "use-soft-float");
|
|
||||||
|
|
||||||
// Skip if function has "use-soft-float" attribute.
|
|
||||||
if ((A.isStringAttribute() && (A.getValueAsString() == "true")) ||
|
|
||||||
TM.Options.UseSoftFloat)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip if function either has local linkage or is not a known library
|
// Skip if function either has local linkage or is not a known library
|
||||||
// function.
|
// function.
|
||||||
|
LibFunc::Func LibFunc;
|
||||||
if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
|
if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
|
||||||
!LibInfo->getLibFunc(CalledFunc->getName(), LibFunc))
|
!TLI->getLibFunc(CalledFunc->getName(), LibFunc))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (LibFunc) {
|
switch (LibFunc) {
|
||||||
case LibFunc::sqrtf:
|
case LibFunc::sqrtf:
|
||||||
case LibFunc::sqrt:
|
case LibFunc::sqrt:
|
||||||
if (optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
|
if (TTI->haveFastSqrt(Call->getType()) &&
|
||||||
|
optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@@ -121,10 +98,10 @@ bool MipsOptimizeMathLibCalls::runOnFunction(Function &F) {
|
|||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MipsOptimizeMathLibCalls::optimizeSQRT(CallInst *Call,
|
bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call,
|
||||||
Function *CalledFunc,
|
Function *CalledFunc,
|
||||||
BasicBlock &CurrBB,
|
BasicBlock &CurrBB,
|
||||||
Function::iterator &BB) {
|
Function::iterator &BB) {
|
||||||
// There is no need to change the IR, since backend will emit sqrt
|
// There is no need to change the IR, since backend will emit sqrt
|
||||||
// instruction if the call has already been marked read-only.
|
// instruction if the call has already been marked read-only.
|
||||||
if (Call->onlyReadsMemory())
|
if (Call->onlyReadsMemory())
|
||||||
@@ -173,3 +150,7 @@ bool MipsOptimizeMathLibCalls::optimizeSQRT(CallInst *Call,
|
|||||||
BB = JoinBB;
|
BB = JoinBB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionPass *llvm::createPartiallyInlineLibCallsPass() {
|
||||||
|
return new PartiallyInlineLibCalls();
|
||||||
|
}
|
@@ -50,6 +50,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
|
|||||||
initializeLowerAtomicPass(Registry);
|
initializeLowerAtomicPass(Registry);
|
||||||
initializeLowerExpectIntrinsicPass(Registry);
|
initializeLowerExpectIntrinsicPass(Registry);
|
||||||
initializeMemCpyOptPass(Registry);
|
initializeMemCpyOptPass(Registry);
|
||||||
|
initializePartiallyInlineLibCallsPass(Registry);
|
||||||
initializeReassociatePass(Registry);
|
initializeReassociatePass(Registry);
|
||||||
initializeRegToMemPass(Registry);
|
initializeRegToMemPass(Registry);
|
||||||
initializeSCCPPass(Registry);
|
initializeSCCPPass(Registry);
|
||||||
@@ -123,6 +124,10 @@ void LLVMAddMemCpyOptPass(LLVMPassManagerRef PM) {
|
|||||||
unwrap(PM)->add(createMemCpyOptPass());
|
unwrap(PM)->add(createMemCpyOptPass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLVMAddPartiallyInlineLibCallsPass(LLVMPassManagerRef PM) {
|
||||||
|
unwrap(PM)->add(createPartiallyInlineLibCallsPass());
|
||||||
|
}
|
||||||
|
|
||||||
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM) {
|
void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM) {
|
||||||
unwrap(PM)->add(createPromoteMemoryToRegisterPass());
|
unwrap(PM)->add(createPromoteMemoryToRegisterPass());
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,8 @@
|
|||||||
;
|
;
|
||||||
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
declare float @llvm.sqrt.f32(float %f)
|
declare float @llvm.sqrt.f32(float)
|
||||||
|
declare float @sqrtf(float)
|
||||||
|
|
||||||
; Check register square root.
|
; Check register square root.
|
||||||
define float @f1(float %val) {
|
define float @f1(float %val) {
|
||||||
@@ -152,3 +153,17 @@ define void @f7(float *%ptr) {
|
|||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Check that a call to the normal sqrtf function is lowered.
|
||||||
|
define float @f8(float %dummy, float %val) {
|
||||||
|
; CHECK-LABEL: f8:
|
||||||
|
; CHECK: sqebr %f0, %f2
|
||||||
|
; CHECK: cebr %f0, %f0
|
||||||
|
; CHECK: jo [[LABEL:\.L.*]]
|
||||||
|
; CHECK: br %r14
|
||||||
|
; CHECK: [[LABEL]]:
|
||||||
|
; CHECK: ler %f0, %f2
|
||||||
|
; CHECK: jg sqrtf@PLT
|
||||||
|
%res = tail call float @sqrtf(float %val)
|
||||||
|
ret float %res
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
declare double @llvm.sqrt.f64(double %f)
|
declare double @llvm.sqrt.f64(double %f)
|
||||||
|
declare double @sqrt(double)
|
||||||
|
|
||||||
; Check register square root.
|
; Check register square root.
|
||||||
define double @f1(double %val) {
|
define double @f1(double %val) {
|
||||||
@@ -152,3 +153,17 @@ define void @f7(double *%ptr) {
|
|||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Check that a call to the normal sqrt function is lowered.
|
||||||
|
define double @f8(double %dummy, double %val) {
|
||||||
|
; CHECK-LABEL: f8:
|
||||||
|
; CHECK: sqdbr %f0, %f2
|
||||||
|
; CHECK: cdbr %f0, %f0
|
||||||
|
; CHECK: jo [[LABEL:\.L.*]]
|
||||||
|
; CHECK: br %r14
|
||||||
|
; CHECK: [[LABEL]]:
|
||||||
|
; CHECK: ldr %f0, %f2
|
||||||
|
; CHECK: jg sqrt@PLT
|
||||||
|
%res = tail call double @sqrt(double %val)
|
||||||
|
ret double %res
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user