Skip to content

Commit 4f219ea

Browse files
committed
Small fixes
- Add method `hasFloatingPointBundles` to simplify checks, - Update comments in `TailRecursionElimination.cpp`, - Updated messages in Verifier, - Add Verifier tests. - Rebame remained cases of 'fpe.round' for 'fpe.control'
1 parent 4989e7b commit 4f219ea

File tree

8 files changed

+116
-17
lines changed

8 files changed

+116
-17
lines changed

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,9 @@ class CallBase : public Instruction {
21692169
/// Return exception behavior specified by operand bundles.
21702170
std::optional<fp::ExceptionBehavior> getExceptionBehavior() const;
21712171

2172+
// Does the called function have floating-point bundles?
2173+
bool hasFloatingPointBundles() const;
2174+
21722175
/// Used to keep track of an operand bundle. See the main comment on
21732176
/// OperandBundleUser above.
21742177
struct BundleOpInfo {

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4330,8 +4330,7 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) {
43304330

43314331
static CallBase *upgradeConstrainedIntrinsicCall(CallBase *CB, Function *F,
43324332
IRBuilder<> &Builder) {
4333-
if (CB->getOperandBundle(LLVMContext::OB_fpe_control) ||
4334-
CB->getOperandBundle(LLVMContext::OB_fpe_except))
4333+
if (CB->hasFloatingPointBundles())
43354334
return nullptr;
43364335

43374336
SmallVector<OperandBundleDef, 2> NewBundles;

llvm/lib/IR/IRBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ CallInst *IRBuilderBase::CreateCall(FunctionType *FTy, Value *Callee,
9999
if (IntrinsicInst::canAccessFPEnvironment(ID)) {
100100
bool NeedRound = true, NeedExcept = true;
101101
for (const auto &Item : OpBundles) {
102-
if (NeedRound && Item.getTag() == "fpe.round")
102+
if (NeedRound && Item.getTag() == "fpe.control")
103103
NeedRound = false;
104104
else if (NeedExcept && Item.getTag() == "fpe.except")
105105
NeedExcept = false;

llvm/lib/IR/Instructions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,11 @@ std::optional<fp::ExceptionBehavior> CallBase::getExceptionBehavior() const {
639639
return std::nullopt;
640640
}
641641

642+
bool CallBase::hasFloatingPointBundles() const {
643+
return getOperandBundle(LLVMContext::OB_fpe_control) ||
644+
getOperandBundle(LLVMContext::OB_fpe_except);
645+
}
646+
642647
MemoryEffects CallBase::getMemoryEffects() const {
643648
MemoryEffects ME = getAttributes().getMemoryEffects();
644649
if (auto *Fn = dyn_cast<Function>(getCalledOperand())) {

llvm/lib/IR/LLVMContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
8484

8585
auto *RoundingEntry = pImpl->getOrInsertBundleTag("fpe.control");
8686
assert(RoundingEntry->second == LLVMContext::OB_fpe_control &&
87-
"fpe.round operand bundle id drifted!");
87+
"fpe.control operand bundle id drifted!");
8888
(void)RoundingEntry;
8989

9090
auto *ExceptionEntry = pImpl->getOrInsertBundleTag("fpe.except");

llvm/lib/IR/Verifier.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3731,7 +3731,7 @@ void Verifier::visitCallBase(CallBase &Call) {
37313731
FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false,
37323732
FoundPreallocatedBundle = false, FoundGCLiveBundle = false,
37333733
FoundPtrauthBundle = false, FoundKCFIBundle = false,
3734-
FoundAttachedCallBundle = false, FoundFpeRoundBundle = false,
3734+
FoundAttachedCallBundle = false, FoundFpeControlBundle = false,
37353735
FoundFpeExceptBundle = false;
37363736

37373737
for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
@@ -3797,18 +3797,20 @@ void Verifier::visitCallBase(CallBase &Call) {
37973797
FoundAttachedCallBundle = true;
37983798
verifyAttachedCallBundle(Call, BU);
37993799
} else if (Tag == LLVMContext::OB_fpe_control) {
3800-
Check(!FoundFpeRoundBundle, "Multiple fpe.round operand bundles", Call);
3800+
Check(!FoundFpeControlBundle, "Multiple fpe.control operand bundles",
3801+
Call);
38013802
Check(BU.Inputs.size() == 1,
3802-
"Expected exactly one fpe.round bundle operand", Call);
3803+
"Expected exactly one fpe.control bundle operand", Call);
38033804
auto *V = dyn_cast<MetadataAsValue>(BU.Inputs.front());
3804-
Check(V, "Value of fpe.round bundle operand must be a metadata", Call);
3805+
Check(V, "Value of fpe.control bundle operand must be a metadata", Call);
38053806
auto *MDS = dyn_cast<MDString>(V->getMetadata());
3806-
Check(MDS, "Value of fpe.round bundle operand must be a string", Call);
3807+
Check(MDS, "Value of fpe.control bundle operand must be a string", Call);
38073808
auto RM = convertStrToRoundingMode(MDS->getString(), true);
3808-
Check(RM.has_value(),
3809-
"Value of fpe.round bundle operand is not a correct rounding mode",
3810-
Call);
3811-
FoundFpeRoundBundle = true;
3809+
Check(
3810+
RM.has_value(),
3811+
"Value of fpe.control bundle operand is not a correct rounding mode",
3812+
Call);
3813+
FoundFpeControlBundle = true;
38123814
} else if (Tag == LLVMContext::OB_fpe_except) {
38133815
Check(!FoundFpeExceptBundle, "Multiple fpe.except operand bundles", Call);
38143816
Check(BU.Inputs.size() == 1,

llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ static bool markTails(Function &F, OptimizationRemarkEmitter *ORE) {
249249
if (II->getIntrinsicID() == Intrinsic::stackrestore)
250250
continue;
251251

252-
// Special-case operand bundles "clang.arc.attachedcall", "ptrauth", and
253-
// "kcfi".
254252
bool IsNoTail =
255253
CI->isNoTailCall() ||
256254
CI->hasOperandBundlesOtherThan(
257255
{LLVMContext::OB_clang_arc_attachedcall, LLVMContext::OB_ptrauth,
258-
LLVMContext::OB_kcfi, LLVMContext::OB_fpe_control,
259-
LLVMContext::OB_fpe_except});
256+
LLVMContext::OB_kcfi,
257+
// A call with FP operand bundles should be treated in the same
258+
// way as a call without them.
259+
LLVMContext::OB_fpe_control, LLVMContext::OB_fpe_except});
260260

261261
if (!IsNoTail && CI->doesNotAccessMemory()) {
262262
// A call to a readnone function whose arguments are all things computed

llvm/test/Verifier/fp-intrinsics.ll

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,94 @@ entry:
5151
ret double %fadd
5252
}
5353

54+
; Test multiple fpe.control bundles.
55+
; CHECK-NEXT: Multiple fpe.control operand bundles
56+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.control"(metadata !"rtz"), "fpe.control"(metadata !"rtz") ]
57+
define double @f6(double %a) #0 {
58+
entry:
59+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.control"(metadata !"rtz"), "fpe.control"(metadata !"rtz") ]
60+
ret double %ftrunc
61+
}
62+
63+
; Test fpe.control bundle that has more than one operands.
64+
; CHECK-NEXT: Expected exactly one fpe.control bundle operand
65+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.control"(metadata !"rtz", metadata !"rte") ]
66+
define double @f7(double %a) #0 {
67+
entry:
68+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.control"(metadata !"rtz", metadata !"rte") ]
69+
ret double %ftrunc
70+
}
71+
72+
; Test fpe.control bundle that has non-metadata operand.
73+
; CHECK-NEXT: Value of fpe.control bundle operand must be a metadata
74+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.control"(i32 0) ]
75+
define double @f8(double %a) #0 {
76+
entry:
77+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.control"(i32 0) ]
78+
ret double %ftrunc
79+
}
80+
81+
; Test fpe.control bundle that has non-string operand.
82+
; CHECK-NEXT: Value of fpe.control bundle operand must be a string
83+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.control"(metadata i64 3) ]
84+
define double @f9(double %a) #0 {
85+
entry:
86+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.control"(metadata !{i64 3}) ]
87+
ret double %ftrunc
88+
}
89+
90+
; Test fpe.control bundle that specifies incorrect value.
91+
; CHECK-NEXT: Value of fpe.control bundle operand is not a correct rounding mode
92+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.control"(metadata !"qqq") ]
93+
define double @f10(double %a) #0 {
94+
entry:
95+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.control"(metadata !"qqq") ]
96+
ret double %ftrunc
97+
}
98+
99+
; Test multiple fpe.except bundles.
100+
; CHECK-NEXT: Multiple fpe.except operand bundles
101+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.except"(metadata !"strict"), "fpe.except"(metadata !"strict") ]
102+
define double @f11(double %a) #0 {
103+
entry:
104+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.except"(metadata !"strict"), "fpe.except"(metadata !"strict") ]
105+
ret double %ftrunc
106+
}
107+
108+
; Test fpe.except bundle that has more than one operands.
109+
; CHECK-NEXT: Expected exactly one fpe.except bundle operand
110+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.except"(metadata !"strict", metadata !"strict") ]
111+
define double @f12(double %a) #0 {
112+
entry:
113+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.except"(metadata !"strict", metadata !"strict") ]
114+
ret double %ftrunc
115+
}
116+
117+
; Test fpe.except bundle that has non-metadata operand.
118+
; CHECK-NEXT: Value of fpe.except bundle operand must be a metadata
119+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.except"(i32 0) ]
120+
define double @f13(double %a) #0 {
121+
entry:
122+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.except"(i32 0) ]
123+
ret double %ftrunc
124+
}
125+
126+
; Test fpe.except bundle that has non-string operand.
127+
; CHECK-NEXT: Value of fpe.except bundle operand must be a string
128+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.except"(metadata i64 3) ]
129+
define double @f14(double %a) #0 {
130+
entry:
131+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.except"(metadata !{i64 3}) ]
132+
ret double %ftrunc
133+
}
134+
135+
; Test fpe.except bundle that specifies incorrect value.
136+
; CHECK-NEXT: Value of fpe.except bundle operand is not a correct exception behavior
137+
; CHECK-NEXT: %ftrunc = call double @llvm.trunc.f64(double %a) #{{[0-9]+}} [ "fpe.except"(metadata !"qqq") ]
138+
define double @f15(double %a) #0 {
139+
entry:
140+
%ftrunc = call double @llvm.trunc.f64(double %a) #0 [ "fpe.except"(metadata !"qqq") ]
141+
ret double %ftrunc
142+
}
143+
54144
attributes #0 = { strictfp }

0 commit comments

Comments
 (0)