Skip to content

Commit 2b2af2b

Browse files
committed
Use metadata for bundle values
1 parent a4b8a54 commit 2b2af2b

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
@@ -3013,19 +3013,36 @@ Floating-point Environment Operand Bundles
30133013
These operand bundles provide details on how the operation interacts with the
30143014
:ref:`floating-point environment <_floatenv>`. There are two kinds of such
30153015
operand bundles, which characterize interaction with floating-point control
3016-
modes and status bits.
3016+
modes and status bits respectively.
30173017

3018-
An operand bundle tagged with "fpe.round" may be associated with the operations
3019-
that may depend on rounding mode. It has an integer value, which represents
3020-
the rounding mode with the same encoding as ``llvm::RoundingMode`` uses. If it
3021-
is present and is not equal to ``llvm::Dynamic``, it specifies the rounding
3022-
mode, which will be used for the operation evaluation. The value
3023-
``llvm::RoundingMode`` indicates that the rounding mode used by the operation is
3024-
specified in a floating-point control register.
3018+
An operand bundle tagged with "fpe.control" keeps information about control
3019+
modes used by the operation. Only rounding mode is supported now. It is
3020+
represented by a metadata string value and specifies the rounding mode, which
3021+
will be used for the operation evaluation. Possible values are:
3022+
3023+
::
3024+
3025+
"rtz" - toward zero
3026+
"rte" - to nearest, ties to even
3027+
"rtp" - toward positive infinity
3028+
"rtn" - toward negative infinity
3029+
"rmm" - to nearest, ties away from zero
3030+
"dyn" - rounding mode is taken from control register
3031+
3032+
If "fpe.control" is absent, default rounding rounding to nearest, ties to even
3033+
is assumed.
30253034

30263035
An operand bundle tagged with "fpe.except" may be associated with the operations
3027-
that may read or write floating-point exception flags. It has the same meaning
3028-
and encoding as the corresponding argument in
3036+
that may read or write floating-point exception flags. It has a single metadata
3037+
string value, which may have one of the values:
3038+
3039+
::
3040+
3041+
"ignore"
3042+
"strict"
3043+
"maytrap"
3044+
3045+
It has the same meaning as the corresponding argument in
30293046
:ref:`constrained intrinsics <_constrainedfp>`.
30303047

30313048
.. _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
@@ -563,6 +563,11 @@ namespace llvm {
563563
bool resolveFunctionType(Type *RetType, ArrayRef<ParamInfo> ArgList,
564564
FunctionType *&FuncTy);
565565

566+
void updateConstrainedIntrinsic(ValID &CalleeID,
567+
SmallVectorImpl<ParamInfo> &Args,
568+
SmallVectorImpl<OperandBundleDef> &Bundles,
569+
AttrBuilder &FnAttrs);
570+
566571
// Constant Parsing.
567572
bool parseValID(ValID &ID, PerFunctionState *PFS,
568573
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
@@ -1324,15 +1324,6 @@ class IRBuilderBase {
13241324
return I;
13251325
}
13261326

1327-
RoundingMode
1328-
getEffectiveRounding(std::optional<RoundingMode> Rounding = std::nullopt) {
1329-
RoundingMode RM = DefaultConstrainedRounding;
1330-
1331-
if (Rounding)
1332-
RM = *Rounding;
1333-
return RM;
1334-
}
1335-
13361327
Value *getConstrainedFPRounding(std::optional<RoundingMode> Rounding) {
13371328
RoundingMode UseRounding = DefaultConstrainedRounding;
13381329

@@ -1347,14 +1338,6 @@ class IRBuilderBase {
13471338
return MetadataAsValue::get(Context, RoundingMDS);
13481339
}
13491340

1350-
fp::ExceptionBehavior getEffectiveExceptionBehavior(
1351-
std::optional<fp::ExceptionBehavior> Except = std::nullopt) {
1352-
fp::ExceptionBehavior EB = DefaultConstrainedExcept;
1353-
if (Except)
1354-
EB = *Except;
1355-
return EB;
1356-
}
1357-
13581341
Value *getConstrainedFPExcept(std::optional<fp::ExceptionBehavior> Except) {
13591342
std::optional<StringRef> ExceptStr = convertExceptionBehaviorToStr(
13601343
Except.value_or(DefaultConstrainedExcept));
@@ -2469,24 +2452,13 @@ class IRBuilderBase {
24692452
CallInst *CreateCall(FunctionType *FTy, Value *Callee,
24702453
ArrayRef<Value *> Args = {}, const Twine &Name = "",
24712454
MDNode *FPMathTag = nullptr) {
2472-
CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles);
2473-
if (IsFPConstrained)
2474-
setConstrainedFPCallAttr(CI);
2475-
if (isa<FPMathOperator>(CI))
2476-
setFPAttrs(CI, FPMathTag, FMF);
2477-
return Insert(CI, Name);
2455+
return CreateCall(FTy, Callee, Args, DefaultOperandBundles, Name,
2456+
FPMathTag);
24782457
}
24792458

24802459
CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef<Value *> Args,
24812460
ArrayRef<OperandBundleDef> OpBundles,
2482-
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
2483-
CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles);
2484-
if (IsFPConstrained)
2485-
setConstrainedFPCallAttr(CI);
2486-
if (isa<FPMathOperator>(CI))
2487-
setFPAttrs(CI, FPMathTag, FMF);
2488-
return Insert(CI, Name);
2489-
}
2461+
const Twine &Name = "", MDNode *FPMathTag = nullptr);
24902462

24912463
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = {},
24922464
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
@@ -2505,10 +2477,6 @@ class IRBuilderBase {
25052477
Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "",
25062478
std::optional<RoundingMode> Rounding = std::nullopt,
25072479
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
2508-
CallInst *CreateConstrainedFPCall(
2509-
Intrinsic::ID ID, ArrayRef<Value *> Args, const Twine &Name = "",
2510-
std::optional<RoundingMode> Rounding = std::nullopt,
2511-
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
25122480

25132481
Value *CreateSelect(Value *C, Value *True, Value *False,
25142482
const Twine &Name = "", Instruction *MDFrom = nullptr);
@@ -2708,17 +2676,10 @@ class IRBuilderBase {
27082676

27092677
void
27102678
createFPRoundingBundle(SmallVectorImpl<OperandBundleDef> &Bundles,
2711-
std::optional<RoundingMode> Rounding = std::nullopt) {
2712-
int RM = static_cast<int32_t>(getEffectiveRounding(Rounding));
2713-
Bundles.emplace_back("fpe.round", getInt32(RM));
2714-
}
2715-
2679+
std::optional<RoundingMode> Rounding = std::nullopt);
27162680
void createFPExceptionBundle(
27172681
SmallVectorImpl<OperandBundleDef> &Bundles,
2718-
std::optional<fp::ExceptionBehavior> Except = std::nullopt) {
2719-
int EB = getEffectiveExceptionBehavior(Except);
2720-
Bundles.emplace_back("fpe.except", getInt32(EB));
2721-
}
2682+
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
27222683
};
27232684

27242685
/// 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
@@ -1100,6 +1100,13 @@ template <typename InputTy> class OperandBundleDefT {
11001100
using OperandBundleDef = OperandBundleDefT<Value *>;
11011101
using ConstOperandBundleDef = OperandBundleDefT<const Value *>;
11021102

1103+
void addFPRoundingBundle(LLVMContext &Ctx,
1104+
SmallVectorImpl<OperandBundleDef> &Bundles,
1105+
RoundingMode Rounding);
1106+
void addFPExceptionBundle(LLVMContext &Ctx,
1107+
SmallVectorImpl<OperandBundleDef> &Bundles,
1108+
fp::ExceptionBehavior Except);
1109+
11031110
//===----------------------------------------------------------------------===//
11041111
// CallBase Class
11051112
//===----------------------------------------------------------------------===//

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)