Skip to content

Commit 359a022

Browse files
committed
Use metadata for bundle values
1 parent 2b94903 commit 359a022

27 files changed

+657
-230
lines changed

clang/test/CodeGen/strictfp_builtins.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,21 @@ void p(char *str, int x) {
3131
// CHECK-NEXT: [[D_ADDR:%.*]] = alloca double, align 8
3232
// CHECK-NEXT: store double [[D:%.*]], ptr [[D_ADDR]], align 8
3333
// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[D_ADDR]], align 8
34-
// CHECK-NEXT: [[ISZERO:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double 0.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5:[0-9]+]] [ "fpe.except"(i32 2) ]
34+
// CHECK-NEXT: [[ISZERO:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double 0.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5:[0-9]+]] [ "fpe.except"(metadata !"strict") ]
3535
// CHECK-NEXT: br i1 [[ISZERO]], label [[FPCLASSIFY_END:%.*]], label [[FPCLASSIFY_NOT_ZERO:%.*]]
3636
// CHECK: fpclassify_end:
3737
// CHECK-NEXT: [[FPCLASSIFY_RESULT:%.*]] = phi i32 [ 4, [[ENTRY:%.*]] ], [ 0, [[FPCLASSIFY_NOT_ZERO]] ], [ 1, [[FPCLASSIFY_NOT_NAN:%.*]] ], [ [[TMP2:%.*]], [[FPCLASSIFY_NOT_INF:%.*]] ]
3838
// CHECK-NEXT: call void @p(ptr noundef @.str.1, i32 noundef [[FPCLASSIFY_RESULT]]) #[[ATTR4]]
3939
// CHECK-NEXT: ret void
4040
// CHECK: fpclassify_not_zero:
41-
// CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double [[TMP0]], metadata !"uno", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(i32 2) ]
41+
// CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double [[TMP0]], metadata !"uno", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(metadata !"strict") ]
4242
// CHECK-NEXT: br i1 [[CMP]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_NAN]]
4343
// CHECK: fpclassify_not_nan:
4444
// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[TMP0]]) #[[ATTR6:[0-9]+]]
45-
// CHECK-NEXT: [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(i32 2) ]
45+
// CHECK-NEXT: [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(metadata !"strict") ]
4646
// CHECK-NEXT: br i1 [[ISINF]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_INF]]
4747
// CHECK: fpclassify_not_inf:
48-
// CHECK-NEXT: [[ISNORMAL:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x10000000000000, metadata !"uge", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(i32 2) ]
48+
// CHECK-NEXT: [[ISNORMAL:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x10000000000000, metadata !"uge", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(metadata !"strict") ]
4949
// CHECK-NEXT: [[TMP2]] = select i1 [[ISNORMAL]], i32 2, i32 3
5050
// CHECK-NEXT: br label [[FPCLASSIFY_END]]
5151
//
@@ -157,7 +157,7 @@ void test_double_isfinite(double d) {
157157
// CHECK-NEXT: store double [[D:%.*]], ptr [[D_ADDR]], align 8
158158
// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[D_ADDR]], align 8
159159
// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[TMP0]]) #[[ATTR6]]
160-
// CHECK-NEXT: [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(i32 2) ]
160+
// CHECK-NEXT: [[ISINF:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double 0x7FF0000000000000, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.except"(metadata !"strict") ]
161161
// CHECK-NEXT: [[TMP2:%.*]] = bitcast double [[TMP0]] to i64
162162
// CHECK-NEXT: [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 0
163163
// CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 -1, i32 1

clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ kernel void device_side_enqueue(global float *a, global float *b, int i) {
144144
// STRICTFP-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(4) [[BLOCK_CAPTURE_ADDR1]], align 4
145145
// STRICTFP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[TMP0]], i32 [[TMP1]]
146146
// STRICTFP-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX]], align 4
147-
// STRICTFP-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fmuladd.f32(float 4.000000e+00, float [[TMP2]], float 1.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.round"(i32 1), "fpe.except"(i32 2) ]
147+
// STRICTFP-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fmuladd.f32(float 4.000000e+00, float [[TMP2]], float 1.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR5]] [ "fpe.control"(metadata !"rte"), "fpe.except"(metadata !"strict") ]
148148
// STRICTFP-NEXT: [[BLOCK_CAPTURE_ADDR2:%.*]] = getelementptr inbounds nuw <{ i32, i32, ptr addrspace(4), ptr addrspace(1), i32, ptr addrspace(1) }>, ptr addrspace(4) [[DOTBLOCK_DESCRIPTOR]], i32 0, i32 3
149149
// STRICTFP-NEXT: [[TMP4:%.*]] = load ptr addrspace(1), ptr addrspace(4) [[BLOCK_CAPTURE_ADDR2]], align 4
150150
// STRICTFP-NEXT: [[BLOCK_CAPTURE_ADDR3:%.*]] = getelementptr inbounds nuw <{ i32, i32, ptr addrspace(4), ptr addrspace(1), i32, ptr addrspace(1) }>, ptr addrspace(4) [[DOTBLOCK_DESCRIPTOR]], i32 0, i32 4

llvm/docs/LangRef.rst

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,19 +3065,36 @@ Floating-point Environment Operand Bundles
30653065
These operand bundles provide details on how the operation interacts with the
30663066
:ref:`floating-point environment <_floatenv>`. There are two kinds of such
30673067
operand bundles, which characterize interaction with floating-point control
3068-
modes and status bits.
3068+
modes and status bits respectively.
30693069

3070-
An operand bundle tagged with "fpe.round" may be associated with the operations
3071-
that may depend on rounding mode. It has an integer value, which represents
3072-
the rounding mode with the same encoding as ``llvm::RoundingMode`` uses. If it
3073-
is present and is not equal to ``llvm::Dynamic``, it specifies the rounding
3074-
mode, which will be used for the operation evaluation. The value
3075-
``llvm::RoundingMode`` indicates that the rounding mode used by the operation is
3076-
specified in a floating-point control register.
3070+
An operand bundle tagged with "fpe.control" keeps information about control
3071+
modes used by the operation. Only rounding mode is supported now. It is
3072+
represented by a metadata string value and specifies the rounding mode, which
3073+
will be used for the operation evaluation. Possible values are:
3074+
3075+
::
3076+
3077+
"rtz" - toward zero
3078+
"rte" - to nearest, ties to even
3079+
"rtp" - toward positive infinity
3080+
"rtn" - toward negative infinity
3081+
"rmm" - to nearest, ties away from zero
3082+
"dyn" - rounding mode is taken from control register
3083+
3084+
If "fpe.control" is absent, default rounding rounding to nearest, ties to even
3085+
is assumed.
30773086

30783087
An operand bundle tagged with "fpe.except" may be associated with the operations
3079-
that may read or write floating-point exception flags. It has the same meaning
3080-
and encoding as the corresponding argument in
3088+
that may read or write floating-point exception flags. It has a single metadata
3089+
string value, which may have one of the values:
3090+
3091+
::
3092+
3093+
"ignore"
3094+
"strict"
3095+
"maytrap"
3096+
3097+
It has the same meaning as the corresponding argument in
30813098
:ref:`constrained intrinsics <_constrainedfp>`.
30823099

30833100
.. _moduleasm:

llvm/include/llvm/ADT/FloatingPointMode.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ enum class RoundingMode : int8_t {
4747
Invalid = -1 ///< Denotes invalid value.
4848
};
4949

50-
inline bool isValidRoundingMode(int X) {
51-
return X >= 0 && X <= static_cast<int>(RoundingMode::Dynamic);
52-
}
53-
54-
inline RoundingMode castToRoundingMode(int X) {
55-
assert(isValidRoundingMode(X));
56-
return static_cast<RoundingMode>(X);
57-
}
58-
5950
/// Returns text representation of the given rounding mode.
6051
inline StringRef spell(RoundingMode RM) {
6152
switch (RM) {

llvm/include/llvm/AsmParser/LLParser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,11 @@ namespace llvm {
567567
bool resolveFunctionType(Type *RetType, ArrayRef<ParamInfo> ArgList,
568568
FunctionType *&FuncTy);
569569

570+
void updateConstrainedIntrinsic(ValID &CalleeID,
571+
SmallVectorImpl<ParamInfo> &Args,
572+
SmallVectorImpl<OperandBundleDef> &Bundles,
573+
AttrBuilder &FnAttrs);
574+
570575
// Constant Parsing.
571576
bool parseValID(ValID &ID, PerFunctionState *PFS,
572577
Type *ExpectedTy = nullptr);

llvm/include/llvm/IR/FPEnv.h

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,26 @@ enum ExceptionBehavior : uint8_t {
4343

4444
}
4545

46-
inline bool isValidExceptionBehavior(unsigned X) {
47-
return X <= fp::ExceptionBehavior::ebStrict;
48-
}
49-
50-
inline fp::ExceptionBehavior castToExceptionBehavior(unsigned X) {
51-
assert(isValidExceptionBehavior(X));
52-
return static_cast<fp::ExceptionBehavior>(X);
53-
}
54-
5546
/// Returns a valid RoundingMode enumerator when given a string
5647
/// that is valid as input in constrained intrinsic rounding mode
5748
/// metadata.
58-
std::optional<RoundingMode> convertStrToRoundingMode(StringRef);
49+
std::optional<RoundingMode> convertStrToRoundingMode(StringRef,
50+
bool InBundle = false);
5951

6052
/// For any RoundingMode enumerator, returns a string valid as input in
6153
/// constrained intrinsic rounding mode metadata.
62-
std::optional<StringRef> convertRoundingModeToStr(RoundingMode);
54+
std::optional<StringRef> convertRoundingModeToStr(RoundingMode,
55+
bool InBundle = false);
6356

6457
/// Returns a valid ExceptionBehavior enumerator when given a string
6558
/// valid as input in constrained intrinsic exception behavior metadata.
66-
std::optional<fp::ExceptionBehavior> convertStrToExceptionBehavior(StringRef);
59+
std::optional<fp::ExceptionBehavior>
60+
convertStrToExceptionBehavior(StringRef, bool InBundle = false);
6761

6862
/// For any ExceptionBehavior enumerator, returns a string valid as
6963
/// input in constrained intrinsic exception behavior metadata.
70-
std::optional<StringRef> convertExceptionBehaviorToStr(fp::ExceptionBehavior);
64+
std::optional<StringRef> convertExceptionBehaviorToStr(fp::ExceptionBehavior,
65+
bool InBundle = false);
7166

7267
/// Returns true if the exception handling behavior and rounding mode
7368
/// match what is used in the default floating point environment.

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,15 +1344,6 @@ class IRBuilderBase {
13441344
return I;
13451345
}
13461346

1347-
RoundingMode
1348-
getEffectiveRounding(std::optional<RoundingMode> Rounding = std::nullopt) {
1349-
RoundingMode RM = DefaultConstrainedRounding;
1350-
1351-
if (Rounding)
1352-
RM = *Rounding;
1353-
return RM;
1354-
}
1355-
13561347
Value *getConstrainedFPRounding(std::optional<RoundingMode> Rounding) {
13571348
RoundingMode UseRounding = DefaultConstrainedRounding;
13581349

@@ -1367,14 +1358,6 @@ class IRBuilderBase {
13671358
return MetadataAsValue::get(Context, RoundingMDS);
13681359
}
13691360

1370-
fp::ExceptionBehavior getEffectiveExceptionBehavior(
1371-
std::optional<fp::ExceptionBehavior> Except = std::nullopt) {
1372-
fp::ExceptionBehavior EB = DefaultConstrainedExcept;
1373-
if (Except)
1374-
EB = *Except;
1375-
return EB;
1376-
}
1377-
13781361
Value *getConstrainedFPExcept(std::optional<fp::ExceptionBehavior> Except) {
13791362
std::optional<StringRef> ExceptStr = convertExceptionBehaviorToStr(
13801363
Except.value_or(DefaultConstrainedExcept));
@@ -2479,24 +2462,13 @@ class IRBuilderBase {
24792462
CallInst *CreateCall(FunctionType *FTy, Value *Callee,
24802463
ArrayRef<Value *> Args = {}, const Twine &Name = "",
24812464
MDNode *FPMathTag = nullptr) {
2482-
CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles);
2483-
if (IsFPConstrained)
2484-
setConstrainedFPCallAttr(CI);
2485-
if (isa<FPMathOperator>(CI))
2486-
setFPAttrs(CI, FPMathTag, FMF);
2487-
return Insert(CI, Name);
2465+
return CreateCall(FTy, Callee, Args, DefaultOperandBundles, Name,
2466+
FPMathTag);
24882467
}
24892468

24902469
CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef<Value *> Args,
24912470
ArrayRef<OperandBundleDef> OpBundles,
2492-
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
2493-
CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles);
2494-
if (IsFPConstrained)
2495-
setConstrainedFPCallAttr(CI);
2496-
if (isa<FPMathOperator>(CI))
2497-
setFPAttrs(CI, FPMathTag, FMF);
2498-
return Insert(CI, Name);
2499-
}
2471+
const Twine &Name = "", MDNode *FPMathTag = nullptr);
25002472

25012473
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = {},
25022474
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
@@ -2515,10 +2487,6 @@ class IRBuilderBase {
25152487
Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "",
25162488
std::optional<RoundingMode> Rounding = std::nullopt,
25172489
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
2518-
CallInst *CreateConstrainedFPCall(
2519-
Intrinsic::ID ID, ArrayRef<Value *> Args, const Twine &Name = "",
2520-
std::optional<RoundingMode> Rounding = std::nullopt,
2521-
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
25222490

25232491
Value *CreateSelect(Value *C, Value *True, Value *False,
25242492
const Twine &Name = "", Instruction *MDFrom = nullptr);
@@ -2725,17 +2693,10 @@ class IRBuilderBase {
27252693

27262694
void
27272695
createFPRoundingBundle(SmallVectorImpl<OperandBundleDef> &Bundles,
2728-
std::optional<RoundingMode> Rounding = std::nullopt) {
2729-
int RM = static_cast<int32_t>(getEffectiveRounding(Rounding));
2730-
Bundles.emplace_back("fpe.round", getInt32(RM));
2731-
}
2732-
2696+
std::optional<RoundingMode> Rounding = std::nullopt);
27332697
void createFPExceptionBundle(
27342698
SmallVectorImpl<OperandBundleDef> &Bundles,
2735-
std::optional<fp::ExceptionBehavior> Except = std::nullopt) {
2736-
int EB = getEffectiveExceptionBehavior(Except);
2737-
Bundles.emplace_back("fpe.except", getInt32(EB));
2738-
}
2699+
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
27392700
};
27402701

27412702
/// This provides a uniform API for creating instructions and inserting

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,13 @@ template <typename InputTy> class OperandBundleDefT {
10921092
using OperandBundleDef = OperandBundleDefT<Value *>;
10931093
using ConstOperandBundleDef = OperandBundleDefT<const Value *>;
10941094

1095+
void addFPRoundingBundle(LLVMContext &Ctx,
1096+
SmallVectorImpl<OperandBundleDef> &Bundles,
1097+
RoundingMode Rounding);
1098+
void addFPExceptionBundle(LLVMContext &Ctx,
1099+
SmallVectorImpl<OperandBundleDef> &Bundles,
1100+
fp::ExceptionBehavior Except);
1101+
10951102
//===----------------------------------------------------------------------===//
10961103
// CallBase Class
10971104
//===----------------------------------------------------------------------===//

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ class IntrinsicInst : public CallInst {
128128
/// course of IR transformations
129129
static bool mayLowerToFunctionCall(Intrinsic::ID IID);
130130

131+
/// Check if the specified intrinsic can read or write FP environment.
132+
/// Constrained intrinsics are not handled in it.
133+
static bool canAccessFPEnvironment(Intrinsic::ID IID);
134+
131135
/// Methods for support type inquiry through isa, cast, and dyn_cast:
132136
static bool classof(const CallInst *I) {
133137
if (const Function *CF = I->getCalledFunction())
@@ -139,6 +143,9 @@ class IntrinsicInst : public CallInst {
139143
}
140144
};
141145

146+
std::optional<RoundingMode> getRoundingModeArg(const CallBase &I);
147+
std::optional<fp::ExceptionBehavior> getExceptionBehaviorArg(const CallBase &I);
148+
142149
/// Check if \p ID corresponds to a lifetime intrinsic.
143150
static inline bool isLifetimeIntrinsic(Intrinsic::ID ID) {
144151
switch (ID) {

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class LLVMContext {
9696
OB_ptrauth = 7, // "ptrauth"
9797
OB_kcfi = 8, // "kcfi"
9898
OB_convergencectrl = 9, // "convergencectrl"
99-
OB_fpe_round = 10, // "fpe.round"
99+
OB_fpe_control = 10, // "fpe.control"
100100
OB_fpe_except = 11, // "fpe.except"
101101
};
102102

0 commit comments

Comments
 (0)