summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/IRBuilder.h30
-rw-r--r--llvm/lib/IR/IRBuilder.cpp25
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp8
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp4
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp10
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp2
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp4
-rw-r--r--llvm/unittests/IR/IRBuilderTest.cpp48
8 files changed, 90 insertions, 41 deletions
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 70641ba25d2..0af53c5b3f4 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -651,7 +651,7 @@ public:
ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = "");
- // Conveninence function for the common case when CallArgs are filled in using
+ // Convenience function for the common case when CallArgs are filled in using
// makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
// get the Value *.
InvokeInst *
@@ -675,32 +675,34 @@ public:
Type *ResultType,
const Twine &Name = "");
+ /// Create a call to intrinsic \p ID with 1 operand which is mangled on its
+ /// type.
+ CallInst *CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
+ Instruction *FMFSource = nullptr,
+ const Twine &Name = "");
+
/// Create a call to intrinsic \p ID with 2 operands which is mangled on the
/// first type.
- CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID,
- Value *LHS, Value *RHS,
+ CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS,
+ Instruction *FMFSource = nullptr,
const Twine &Name = "");
- /// Create a call to intrinsic \p ID with no operands.
- CallInst *CreateIntrinsic(Intrinsic::ID ID,
- Instruction *FMFSource = nullptr,
- const Twine &Name = "");
-
- /// Create a call to intrinsic \p ID with 1 or more operands assuming the
- /// intrinsic and all operands have the same type. If \p FMFSource is
- /// provided, copy fast-math-flags from that instruction to the intrinsic.
- CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef<Value *> Args,
+ /// Create a call to intrinsic \p ID with \p args, mangled using \p Types. If
+ /// \p FMFSource is provided, copy fast-math-flags from that instruction to
+ /// the intrinsic.
+ CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef<Type *> Types,
+ ArrayRef<Value *> Args,
Instruction *FMFSource = nullptr,
const Twine &Name = "");
/// Create call to the minnum intrinsic.
CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, Name);
+ return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, nullptr, Name);
}
/// Create call to the maxnum intrinsic.
CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS, Name);
+ return CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS, nullptr, Name);
}
private:
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 91c950da71b..a9818995677 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -731,28 +731,29 @@ CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
return createCallHelper(FnGCRelocate, Args, this, Name);
}
-CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID,
- Value *LHS, Value *RHS,
- const Twine &Name) {
+CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
+ Instruction *FMFSource,
+ const Twine &Name) {
Module *M = BB->getModule();
- Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
- return createCallHelper(Fn, { LHS, RHS }, this, Name);
+ Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()});
+ return createCallHelper(Fn, {V}, this, Name, FMFSource);
}
-CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
- Instruction *FMFSource,
- const Twine &Name) {
+CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
+ Value *RHS,
+ Instruction *FMFSource,
+ const Twine &Name) {
Module *M = BB->getModule();
- Function *Fn = Intrinsic::getDeclaration(M, ID);
- return createCallHelper(Fn, {}, this, Name);
+ Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
+ return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource);
}
CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
+ ArrayRef<Type *> Types,
ArrayRef<Value *> Args,
Instruction *FMFSource,
const Twine &Name) {
- assert(!Args.empty() && "Expected at least one argument to intrinsic");
Module *M = BB->getModule();
- Function *Fn = Intrinsic::getDeclaration(M, ID, { Args.front()->getType() });
+ Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
return createCallHelper(Fn, Args, this, Name, FMFSource);
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
index 6fcb92efb04..4dc1e67c573 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
@@ -558,7 +558,7 @@ Value* AMDGPUCodeGenPrepare::expandDivRem24(IRBuilder<> &Builder,
Value *FQM = Builder.CreateFMul(FA, RCP);
// fq = trunc(fqm);
- CallInst* FQ = Builder.CreateIntrinsic(Intrinsic::trunc, { FQM });
+ CallInst *FQ = Builder.CreateUnaryIntrinsic(Intrinsic::trunc, FQM);
FQ->copyFastMathFlags(Builder.getFastMathFlags());
// float fqneg = -fq;
@@ -566,17 +566,17 @@ Value* AMDGPUCodeGenPrepare::expandDivRem24(IRBuilder<> &Builder,
// float fr = mad(fqneg, fb, fa);
Value *FR = Builder.CreateIntrinsic(Intrinsic::amdgcn_fmad_ftz,
- { FQNeg, FB, FA }, FQ);
+ {FQNeg->getType()}, {FQNeg, FB, FA}, FQ);
// int iq = (int)fq;
Value *IQ = IsSigned ? Builder.CreateFPToSI(FQ, I32Ty)
: Builder.CreateFPToUI(FQ, I32Ty);
// fr = fabs(fr);
- FR = Builder.CreateIntrinsic(Intrinsic::fabs, { FR }, FQ);
+ FR = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, FR, FQ);
// fb = fabs(fb);
- FB = Builder.CreateIntrinsic(Intrinsic::fabs, { FB }, FQ);
+ FB = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, FB, FQ);
// int cv = fr >= fb;
Value *CV = Builder.CreateFCmpOGE(FR, FB);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
index 2a25f1afa65..fae1da92337 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
@@ -83,8 +83,8 @@ bool AMDGPULowerKernelArguments::runOnFunction(Function &F) {
return false;
CallInst *KernArgSegment =
- Builder.CreateIntrinsic(Intrinsic::amdgcn_kernarg_segment_ptr, nullptr,
- F.getName() + ".kernarg.segment");
+ Builder.CreateIntrinsic(Intrinsic::amdgcn_kernarg_segment_ptr, {}, {},
+ nullptr, F.getName() + ".kernarg.segment");
KernArgSegment->addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
KernArgSegment->addAttribute(AttributeList::ReturnIndex,
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index efe41b49274..4e404933a22 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -709,7 +709,7 @@ static Value *simplifyX86round(IntrinsicInst &II,
}
Intrinsic::ID ID = (RoundControl == 2) ? Intrinsic::ceil : Intrinsic::floor;
- Value *Res = Builder.CreateIntrinsic(ID, {Src}, &II);
+ Value *Res = Builder.CreateUnaryIntrinsic(ID, Src, &II);
if (!IsScalar) {
if (auto *C = dyn_cast<Constant>(Mask))
if (C->isAllOnesValue())
@@ -2038,7 +2038,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// maxnum(-X, -Y) --> -(minnum(X, Y))
Intrinsic::ID NewIID = II->getIntrinsicID() == Intrinsic::maxnum ?
Intrinsic::minnum : Intrinsic::maxnum;
- Value *NewCall = Builder.CreateIntrinsic(NewIID, { X, Y }, II);
+ Value *NewCall = Builder.CreateBinaryIntrinsic(NewIID, X, Y, II);
Instruction *FNeg = BinaryOperator::CreateFNeg(NewCall);
FNeg->copyIRFlags(II);
return FNeg;
@@ -2116,8 +2116,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
Value *ExtSrc;
if (match(II->getArgOperand(0), m_OneUse(m_FPExt(m_Value(ExtSrc))))) {
// Narrow the call: intrinsic (fpext x) -> fpext (intrinsic x)
- Value *NarrowII = Builder.CreateIntrinsic(II->getIntrinsicID(),
- { ExtSrc }, II);
+ Value *NarrowII =
+ Builder.CreateUnaryIntrinsic(II->getIntrinsicID(), ExtSrc, II);
return new FPExtInst(NarrowII, II->getType());
}
break;
@@ -2138,7 +2138,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
Value *X;
if (match(II->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X))))) {
// sin(-x) --> -sin(x)
- Value *NewSin = Builder.CreateIntrinsic(Intrinsic::sin, { X }, II);
+ Value *NewSin = Builder.CreateUnaryIntrinsic(Intrinsic::sin, X, II);
Instruction *FNeg = BinaryOperator::CreateFNeg(NewSin);
FNeg->copyFastMathFlags(II);
return FNeg;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index f99dba49cb5..6427c818e02 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -433,7 +433,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
match(Op0, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(X)))) &&
match(Op1, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(Y))))) {
Value *XY = Builder.CreateFMulFMF(X, Y, &I);
- Value *Sqrt = Builder.CreateIntrinsic(Intrinsic::sqrt, { XY }, &I);
+ Value *Sqrt = Builder.CreateUnaryIntrinsic(Intrinsic::sqrt, XY, &I);
return replaceInstUsesWith(I, Sqrt);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index f42deff7409..3d346dff2f8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1751,7 +1751,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
match(TrueVal, m_FSub(m_PosZeroFP(), m_Specific(X)))) ||
(X == TrueVal && Pred == FCmpInst::FCMP_OGT &&
match(FalseVal, m_FSub(m_PosZeroFP(), m_Specific(X))))) {
- Value *Fabs = Builder.CreateIntrinsic(Intrinsic::fabs, { X }, FCI);
+ Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, X, FCI);
return replaceInstUsesWith(SI, Fabs);
}
// With nsz:
@@ -1764,7 +1764,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
(Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_OLE)) ||
(X == TrueVal && match(FalseVal, m_FNeg(m_Specific(X))) &&
(Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_OGE)))) {
- Value *Fabs = Builder.CreateIntrinsic(Intrinsic::fabs, { X }, FCI);
+ Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, X, FCI);
return replaceInstUsesWith(SI, Fabs);
}
}
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index 720967cb136..42c0393d382 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -51,10 +51,14 @@ protected:
TEST_F(IRBuilderTest, Intrinsics) {
IRBuilder<> Builder(BB);
Value *V;
+ Instruction *I;
CallInst *Call;
IntrinsicInst *II;
V = Builder.CreateLoad(GV);
+ I = cast<Instruction>(Builder.CreateFAdd(V, V));
+ I->setHasNoInfs(true);
+ I->setHasNoNaNs(false);
Call = Builder.CreateMinNum(V, V);
II = cast<IntrinsicInst>(Call);
@@ -64,9 +68,51 @@ TEST_F(IRBuilderTest, Intrinsics) {
II = cast<IntrinsicInst>(Call);
EXPECT_EQ(II->getIntrinsicID(), Intrinsic::maxnum);
- Call = Builder.CreateIntrinsic(Intrinsic::readcyclecounter);
+ Call = Builder.CreateIntrinsic(Intrinsic::readcyclecounter, {}, {});
II = cast<IntrinsicInst>(Call);
EXPECT_EQ(II->getIntrinsicID(), Intrinsic::readcyclecounter);
+
+ Call = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, V);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fabs);
+ EXPECT_FALSE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, V, I);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fabs);
+ EXPECT_TRUE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateBinaryIntrinsic(Intrinsic::pow, V, V);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::pow);
+ EXPECT_FALSE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateBinaryIntrinsic(Intrinsic::pow, V, V, I);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::pow);
+ EXPECT_TRUE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateIntrinsic(Intrinsic::fma, {V->getType()}, {V, V, V});
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);
+ EXPECT_FALSE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateIntrinsic(Intrinsic::fma, {V->getType()}, {V, V, V}, I);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);
+ EXPECT_TRUE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
+
+ Call = Builder.CreateIntrinsic(Intrinsic::fma, {V->getType()}, {V, V, V}, I);
+ II = cast<IntrinsicInst>(Call);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::fma);
+ EXPECT_TRUE(II->hasNoInfs());
+ EXPECT_FALSE(II->hasNoNaNs());
}
TEST_F(IRBuilderTest, Lifetime) {
OpenPOWER on IntegriCloud