[clang] [llvm] [LLVM][IRBuilder] Add `CreateIntrinsicWithoutFolding` overloads (PR #207354)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 3 01:43:18 PDT 2026
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/207354
None
>From e586e4aaaad5967f0bf436dec72e18681999c3d0 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Fri, 3 Jul 2026 01:41:32 -0700
Subject: [PATCH] [LLVM][IRBuilder] Add `CreateIntrinsicWithoutFolding`
overloads
---
clang/lib/CodeGen/TargetBuiltins/SPIR.cpp | 2 +-
llvm/include/llvm/IR/IRBuilder.h | 31 +++++++--
llvm/lib/IR/IRBuilder.cpp | 67 ++++++++-----------
.../AMDGPU/AMDGPULowerKernelArguments.cpp | 2 +-
.../Target/DirectX/DXILIntrinsicExpansion.cpp | 10 +--
llvm/lib/Transforms/IPO/FatLTOCleanup.cpp | 6 +-
llvm/unittests/IR/IRBuilderTest.cpp | 8 +--
7 files changed, 66 insertions(+), 60 deletions(-)
diff --git a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
index b2732e2ae674e..987af98e9230b 100644
--- a/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
@@ -105,7 +105,7 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
"GenericCastToPtrExplicit doesn't return a pointer");
llvm::CallInst *Call = Builder.CreateIntrinsicWithoutFolding(
/*ReturnType=*/Res, Intrinsic::spv_generic_cast_to_ptr_explicit,
- ArrayRef<Value *>{Ptr}, nullptr, "spv.generic_cast");
+ ArrayRef<Value *>{Ptr}, "spv.generic_cast");
Call->addRetAttr(llvm::Attribute::AttrKind::NoUndef);
return Call;
}
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 692990f93c6fb..cc3b97f36b792 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -971,9 +971,27 @@ class IRBuilderBase {
/// that instruction to the intrinsic. It is guaranteed not to fold.
LLVM_ABI CallInst *CreateIntrinsicWithoutFolding(
Intrinsic::ID ID, ArrayRef<Type *> OverloadTypes, ArrayRef<Value *> Args,
- FMFSource FMFSource = {}, const Twine &Name = "",
+ FMFSource FMFSource, const Twine &Name = "",
ArrayRef<OperandBundleDef> OpBundles = {});
+ /// Create a call to intrinsic \p ID with \p Args, mangled using
+ /// \p OverloadTypes. It is guaranteed not to fold.
+ LLVM_ABI CallInst *CreateIntrinsicWithoutFolding(
+ Intrinsic::ID ID, ArrayRef<Type *> OverloadTypes, ArrayRef<Value *> Args,
+ const Twine &Name, ArrayRef<OperandBundleDef> OpBundles = {}) {
+ return CreateIntrinsicWithoutFolding(ID, OverloadTypes, Args, {}, Name,
+ OpBundles);
+ }
+
+ /// Create a call to intrinsic \p ID with \p Args, mangled using
+ /// \p OverloadTypes. It is guaranteed not to fold.
+ LLVM_ABI CallInst *
+ CreateIntrinsicWithoutFolding(Intrinsic::ID ID,
+ ArrayRef<Type *> OverloadTypes,
+ ArrayRef<Value *> Args) {
+ return CreateIntrinsicWithoutFolding(ID, OverloadTypes, Args, FMFSource{});
+ }
+
/// Create a call to intrinsic \p ID with \p RetTy and \p Args. If
/// \p FMFSource is provided, copy fast-math-flags from that instruction to
/// the intrinsic. It is guaranteed not to fold.
@@ -1139,15 +1157,14 @@ class IRBuilderBase {
/// Create a call to llvm.stacksave
CallInst *CreateStackSave(const Twine &Name = "") {
const DataLayout &DL = BB->getDataLayout();
- return CreateIntrinsicWithoutFolding(Intrinsic::stacksave,
- {DL.getAllocaPtrType(Context)}, {},
- nullptr, Name);
+ return CreateIntrinsicWithoutFolding(
+ Intrinsic::stacksave, {DL.getAllocaPtrType(Context)}, {}, Name);
}
/// Create a call to llvm.stackrestore
CallInst *CreateStackRestore(Value *Ptr, const Twine &Name = "") {
- return CreateIntrinsicWithoutFolding(
- Intrinsic::stackrestore, {Ptr->getType()}, {Ptr}, nullptr, Name);
+ return CreateIntrinsicWithoutFolding(Intrinsic::stackrestore,
+ {Ptr->getType()}, {Ptr}, Name);
}
/// Create a call to llvm.experimental_cttz_elts
@@ -1895,7 +1912,7 @@ class IRBuilderBase {
const DataLayout &DL = BB->getDataLayout();
PointerType *PtrTy = DL.getAllocaPtrType(Context);
auto *Output = CreateIntrinsicWithoutFolding(Intrinsic::structured_alloca,
- {PtrTy}, {}, {}, Name);
+ {PtrTy}, {}, Name);
Output->addRetAttr(
Attribute::get(getContext(), Attribute::ElementType, BaseType));
return Output;
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index df738faad7842..5794c005d30c6 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -501,14 +501,14 @@ CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr) {
assert(isa<PointerType>(Ptr->getType()) &&
"lifetime.start only applies to pointers.");
return CreateIntrinsicWithoutFolding(Intrinsic::lifetime_start,
- {Ptr->getType()}, {Ptr});
+ Ptr->getType(), Ptr);
}
CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr) {
assert(isa<PointerType>(Ptr->getType()) &&
"lifetime.end only applies to pointers.");
- return CreateIntrinsicWithoutFolding(Intrinsic::lifetime_end,
- {Ptr->getType()}, {Ptr});
+ return CreateIntrinsicWithoutFolding(Intrinsic::lifetime_end, Ptr->getType(),
+ Ptr);
}
CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
@@ -521,11 +521,9 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
assert(Size->getType() == getInt64Ty() &&
"invariant.start requires the size to be an i64");
- Value *Ops[] = {Size, Ptr};
// Fill in the single overloaded type: memory object type.
- Type *ObjectPtr[1] = {Ptr->getType()};
- return CreateIntrinsicWithoutFolding(Intrinsic::invariant_start, ObjectPtr,
- Ops);
+ return CreateIntrinsicWithoutFolding(Intrinsic::invariant_start,
+ Ptr->getType(), {Size, Ptr});
}
static MaybeAlign getAlign(Value *Ptr) {
@@ -540,7 +538,7 @@ CallInst *IRBuilderBase::CreateThreadLocalAddress(Value *Ptr) {
assert(isa<GlobalValue>(Ptr) && cast<GlobalValue>(Ptr)->isThreadLocal() &&
"threadlocal_address only applies to thread local variables.");
CallInst *CI = CreateIntrinsicWithoutFolding(
- llvm::Intrinsic::threadlocal_address, {Ptr->getType()}, {Ptr});
+ llvm::Intrinsic::threadlocal_address, Ptr->getType(), Ptr);
if (MaybeAlign A = getAlign(Ptr)) {
CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), *A));
CI->addRetAttr(Attribute::getWithAlignment(CI->getContext(), *A));
@@ -552,20 +550,19 @@ CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
assert(Cond->getType() == getInt1Ty() &&
"an assumption condition must be of type i1");
return CreateIntrinsicWithoutFolding(Intrinsic::assume, /*OverloadTypes=*/{},
- {Cond});
+ Cond);
}
CallInst *
IRBuilderBase::CreateAssumption(ArrayRef<OperandBundleDef> OpBundles) {
- Value *Args[] = {ConstantInt::getTrue(getContext())};
- return CreateIntrinsicWithoutFolding(
- Intrinsic::assume, /*OverloadTypes=*/{}, Args,
- /*FMFSource=*/nullptr, /*Name=*/"", OpBundles);
+ return CreateIntrinsicWithoutFolding(Intrinsic::assume, /*OverloadTypes=*/{},
+ ConstantInt::getTrue(getContext()),
+ /*Name=*/"", OpBundles);
}
Instruction *IRBuilderBase::CreateNoAliasScopeDeclaration(Value *Scope) {
return CreateIntrinsicWithoutFolding(
- Intrinsic::experimental_noalias_scope_decl, {}, {Scope});
+ Intrinsic::experimental_noalias_scope_decl, {}, Scope);
}
/// Create a call to a Masked Load intrinsic.
@@ -620,7 +617,7 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
ArrayRef<Value *> Ops,
ArrayRef<Type *> OverloadedTypes,
const Twine &Name) {
- return CreateIntrinsicWithoutFolding(Id, OverloadedTypes, Ops, {}, Name);
+ return CreateIntrinsicWithoutFolding(Id, OverloadedTypes, Ops, Name);
}
/// Create a call to a Masked Gather intrinsic.
@@ -885,36 +882,30 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
Type *ResultType, const Twine &Name) {
- Intrinsic::ID ID = Intrinsic::experimental_gc_result;
- Type *Types[] = {ResultType};
-
- Value *Args[] = {Statepoint};
- return CreateIntrinsicWithoutFolding(ID, Types, Args, {}, Name);
+ return CreateIntrinsicWithoutFolding(Intrinsic::experimental_gc_result,
+ ResultType, Statepoint, Name);
}
CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
int BaseOffset, int DerivedOffset,
Type *ResultType, const Twine &Name) {
- Type *Types[] = {ResultType};
-
Value *Args[] = {Statepoint, getInt32(BaseOffset), getInt32(DerivedOffset)};
return CreateIntrinsicWithoutFolding(Intrinsic::experimental_gc_relocate,
- Types, Args, {}, Name);
+ ResultType, Args, Name);
}
CallInst *IRBuilderBase::CreateGCGetPointerBase(Value *DerivedPtr,
const Twine &Name) {
Type *PtrTy = DerivedPtr->getType();
return CreateIntrinsicWithoutFolding(
- Intrinsic::experimental_gc_get_pointer_base, PtrTy, DerivedPtr, {}, Name);
+ Intrinsic::experimental_gc_get_pointer_base, PtrTy, DerivedPtr, Name);
}
CallInst *IRBuilderBase::CreateGCGetPointerOffset(Value *DerivedPtr,
const Twine &Name) {
Type *PtrTy = DerivedPtr->getType();
return CreateIntrinsicWithoutFolding(
- Intrinsic::experimental_gc_get_pointer_offset, {PtrTy}, {DerivedPtr}, {},
- Name);
+ Intrinsic::experimental_gc_get_pointer_offset, PtrTy, DerivedPtr, Name);
}
Value *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *Op,
@@ -998,8 +989,8 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
Value *ExceptV = getConstrainedFPExcept(Except);
FastMathFlags UseFMF = FMFSource.get(FMF);
- CallInst *C = CreateIntrinsicWithoutFolding(
- ID, {L->getType()}, {L, R, RoundingV, ExceptV}, nullptr, Name, {});
+ CallInst *C = CreateIntrinsicWithoutFolding(ID, L->getType(),
+ {L, R, RoundingV, ExceptV}, Name);
setConstrainedFPCallAttr(C);
setFPAttrs(C, FPMathTag, UseFMF);
return C;
@@ -1015,11 +1006,10 @@ CallInst *IRBuilderBase::CreateConstrainedFPIntrinsic(
FastMathFlags UseFMF = FMFSource.get(FMF);
- llvm::SmallVector<Value *, 5> ExtArgs(Args);
+ SmallVector<Value *, 5> ExtArgs(Args);
ExtArgs.push_back(RoundingV);
ExtArgs.push_back(ExceptV);
- CallInst *C =
- CreateIntrinsicWithoutFolding(ID, Types, ExtArgs, nullptr, Name, {});
+ CallInst *C = CreateIntrinsicWithoutFolding(ID, Types, ExtArgs, Name);
setConstrainedFPCallAttr(C);
setFPAttrs(C, FPMathTag, UseFMF);
return C;
@@ -1032,8 +1022,8 @@ CallInst *IRBuilderBase::CreateConstrainedFPUnroundedBinOp(
Value *ExceptV = getConstrainedFPExcept(Except);
FastMathFlags UseFMF = FMFSource.get(FMF);
- CallInst *C = CreateIntrinsicWithoutFolding(
- ID, {L->getType()}, {L, R, ExceptV}, nullptr, Name, {});
+ CallInst *C =
+ CreateIntrinsicWithoutFolding(ID, L->getType(), {L, R, ExceptV}, Name);
setConstrainedFPCallAttr(C);
setFPAttrs(C, FPMathTag, UseFMF);
return C;
@@ -1065,11 +1055,12 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast(
CallInst *C;
if (Intrinsic::hasConstrainedFPRoundingModeOperand(ID)) {
Value *RoundingV = getConstrainedFPRounding(Rounding);
- C = CreateIntrinsicWithoutFolding(
- ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV}, nullptr, Name, {});
- } else
+ C = CreateIntrinsicWithoutFolding(ID, {DestTy, V->getType()},
+ {V, RoundingV, ExceptV}, Name);
+ } else {
C = CreateIntrinsicWithoutFolding(ID, {DestTy, V->getType()}, {V, ExceptV},
- nullptr, Name, {});
+ Name);
+ }
setConstrainedFPCallAttr(C);
if (isa<FPMathOperator>(C))
@@ -1101,7 +1092,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCmp(
Value *ExceptV = getConstrainedFPExcept(Except);
CallInst *C = CreateIntrinsicWithoutFolding(
- ID, {L->getType()}, {L, R, PredicateV, ExceptV}, nullptr, Name, {});
+ ID, {L->getType()}, {L, R, PredicateV, ExceptV}, Name);
setConstrainedFPCallAttr(C);
return C;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
index b6168a52bb2ef..ff952f15bb23e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp
@@ -222,7 +222,7 @@ static bool lowerKernelArguments(Function &F, const TargetMachine &TM,
return false;
CallInst *KernArgSegment = Builder.CreateIntrinsicWithoutFolding(
- Intrinsic::amdgcn_kernarg_segment_ptr, {}, nullptr,
+ Intrinsic::amdgcn_kernarg_segment_ptr, {},
F.getName() + ".kernarg.segment");
KernArgSegment->addRetAttr(Attribute::NonNull);
KernArgSegment->addRetAttr(
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index 2a91ea223ed2d..299f1f67dff0e 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -445,7 +445,7 @@ static Value *expandExpIntrinsic(CallInst *Orig) {
: ConstantFP::get(EltTy, numbers::log2ef);
Value *NewX = Builder.CreateFMul(Log2eConst, X);
CallInst *Exp2Call = Builder.CreateIntrinsicWithoutFolding(
- Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2");
+ Ty, Intrinsic::exp2, {NewX}, "dx.exp2");
Exp2Call->setTailCall(Orig->isTailCall());
Exp2Call->setAttributes(Orig->getAttributes());
return Exp2Call;
@@ -571,7 +571,7 @@ static Value *expandLogIntrinsic(CallInst *Orig,
ConstantFP::get(EltTy, LogConstVal))
: ConstantFP::get(EltTy, LogConstVal);
CallInst *Log2Call = Builder.CreateIntrinsicWithoutFolding(
- Ty, Intrinsic::log2, {X}, nullptr, "elt.log2");
+ Ty, Intrinsic::log2, {X}, "elt.log2");
Log2Call->setTailCall(Orig->isTailCall());
Log2Call->setAttributes(Orig->getAttributes());
return Builder.CreateFMul(Ln2Const, Log2Call);
@@ -626,8 +626,8 @@ static Value *expandAtan2Intrinsic(CallInst *Orig) {
Value *Tan = Builder.CreateFDiv(Y, X);
- CallInst *Atan = Builder.CreateIntrinsicWithoutFolding(
- Ty, Intrinsic::atan, {Tan}, nullptr, "Elt.Atan");
+ CallInst *Atan = Builder.CreateIntrinsicWithoutFolding(Ty, Intrinsic::atan,
+ {Tan}, "Elt.Atan");
Atan->setTailCall(Orig->isTailCall());
Atan->setAttributes(Orig->getAttributes());
@@ -736,7 +736,7 @@ static Value *expandPowIntrinsic(CallInst *Orig, Intrinsic::ID IntrinsicId) {
Builder.CreateIntrinsic(Ty, Intrinsic::log2, {X}, nullptr, "elt.log2");
auto *Mul = Builder.CreateFMul(Log2Call, Y);
CallInst *Exp2Call = Builder.CreateIntrinsicWithoutFolding(
- Ty, Intrinsic::exp2, {Mul}, nullptr, "elt.exp2");
+ Ty, Intrinsic::exp2, {Mul}, "elt.exp2");
Exp2Call->setTailCall(Orig->isTailCall());
Exp2Call->setAttributes(Orig->getAttributes());
return Exp2Call;
diff --git a/llvm/lib/Transforms/IPO/FatLTOCleanup.cpp b/llvm/lib/Transforms/IPO/FatLTOCleanup.cpp
index eb942d4dd160a..adf20d89763a2 100644
--- a/llvm/lib/Transforms/IPO/FatLTOCleanup.cpp
+++ b/llvm/lib/Transforms/IPO/FatLTOCleanup.cpp
@@ -81,9 +81,9 @@ static bool cleanUpTypeCheckedLoad(Module &M, Function &CheckedLoadFn,
ConstantInt *True = ConstantInt::getTrue(M.getContext());
Instruction *Load;
if (IsRelative) {
- Load = IRB.CreateIntrinsicWithoutFolding(
- Intrinsic::load_relative, {Offset->getType()}, {Ptr, Offset},
- /*FMFSource=*/nullptr, "rel_load");
+ Load = IRB.CreateIntrinsicWithoutFolding(Intrinsic::load_relative,
+ {Offset->getType()},
+ {Ptr, Offset}, "rel_load");
} else {
Value *PtrAdd = IRB.CreatePtrAdd(Ptr, Offset);
Load = IRB.CreateLoad(PtrTy, PtrAdd, "vfunc");
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index 813b1d6e07a3a..20fe7b2e2b584 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -202,8 +202,7 @@ TEST_F(IRBuilderTest, IntrinsicsWithScalableVectors) {
Args.push_back(UndefValue::get(SrcVecTy));
Call = Builder.CreateIntrinsicWithoutFolding(
- Intrinsic::aarch64_sve_fcvtzs_i32f16, Args, nullptr,
- "aarch64.sve.fcvtzs.i32f16");
+ Intrinsic::aarch64_sve_fcvtzs_i32f16, Args, "aarch64.sve.fcvtzs.i32f16");
FTy = Call->getFunctionType();
EXPECT_EQ(FTy->getReturnType(), DstVecTy);
for (unsigned i = 0; i != Args.size(); ++i)
@@ -221,9 +220,8 @@ TEST_F(IRBuilderTest, IntrinsicsWithScalableVectors) {
Args.push_back(UndefValue::get(PredTy));
Args.push_back(UndefValue::get(VecTy));
- Call = Builder.CreateIntrinsicWithoutFolding(Intrinsic::masked_load,
- {VecTy, PtrToVecTy}, Args,
- nullptr, "masked.load");
+ Call = Builder.CreateIntrinsicWithoutFolding(
+ Intrinsic::masked_load, {VecTy, PtrToVecTy}, Args, "masked.load");
FTy = Call->getFunctionType();
EXPECT_EQ(FTy->getReturnType(), VecTy);
for (unsigned i = 0; i != Args.size(); ++i)
More information about the llvm-commits
mailing list