Skip to content

Commit 04b7d82

Browse files
committed
Update nofpclass
1 parent 8d3353c commit 04b7d82

File tree

4 files changed

+36
-22
lines changed

4 files changed

+36
-22
lines changed

llvm/docs/LangRef.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,11 +1499,12 @@ Currently, only the following parameter attributes are defined:
14991499
``nofpclass(<test mask>)``
15001500
This attribute applies to parameters and return values with
15011501
floating-point and vector of floating-point types, as well as
1502-
arrays of such types. The test mask has the same format as the
1503-
second argument to the :ref:`llvm.is.fpclass <llvm.is.fpclass>`,
1504-
and indicates which classes of floating-point values are not
1505-
permitted for the value. For example a bitmask of 3 indicates
1506-
the parameter may not be a NaN.
1502+
:ref:`supported aggregates <fastmath_return_types>` of such types
1503+
(matching the supported types for :ref:`fast-math flags <fastmath>`).
1504+
The test mask has the same format as the second argument to the
1505+
:ref:`llvm.is.fpclass <llvm.is.fpclass>`, and indicates which classes
1506+
of floating-point values are not permitted for the value. For example
1507+
a bitmask of 3 indicates the parameter may not be a NaN.
15071508

15081509
If the value is a floating-point class indicated by the
15091510
``nofpclass`` test mask, a :ref:`poison value <poisonvalues>` is
@@ -3709,12 +3710,12 @@ floating-point transformations.
37093710
argument or zero result as insignificant. This does not imply that -0.0
37103711
is poison and/or guaranteed to not exist in the operation.
37113712

3712-
.. _fastmath_return_types:
3713-
37143713
Note: For :ref:`phi <i_phi>`, :ref:`select <i_select>`, and :ref:`call <i_call>`
37153714
instructions, the following return types are considered to be floating-point
37163715
types:
37173716

3717+
.. _fastmath_return_types:
3718+
37183719
- Floating-point scalar or vector types
37193720
- Array types (nested to any depth) of floating-point scalar or vector types
37203721
- Homogeneous literal struct types of floating-point scalar or vector types

llvm/include/llvm/IR/Operator.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,21 @@ class FPMathOperator : public Operator {
326326
/// precision.
327327
float getFPAccuracy() const;
328328

329+
/// Returns true if `Ty` is a supported floating-point type for phi, select,
330+
/// or call FPMathOperators.
331+
static bool isSupportedFloatingPointType(Type *Ty) {
332+
if (StructType *StructTy = dyn_cast<StructType>(Ty)) {
333+
if (!StructTy->isLiteral() || !StructTy->containsHomogeneousTypes())
334+
return false;
335+
Ty = StructTy->elements().front();
336+
} else if (ArrayType *ArrayTy = dyn_cast<ArrayType>(Ty)) {
337+
do {
338+
Ty = ArrayTy->getElementType();
339+
} while ((ArrayTy = dyn_cast<ArrayType>(Ty)));
340+
}
341+
return Ty->isFPOrFPVectorTy();
342+
}
343+
329344
static bool classof(const Value *V) {
330345
unsigned Opcode;
331346
if (auto *I = dyn_cast<Instruction>(V))
@@ -350,17 +365,7 @@ class FPMathOperator : public Operator {
350365
case Instruction::PHI:
351366
case Instruction::Select:
352367
case Instruction::Call: {
353-
Type *Ty = V->getType();
354-
if (StructType *StructTy = dyn_cast<StructType>(Ty)) {
355-
if (!StructTy->isLiteral() || !StructTy->containsHomogeneousTypes())
356-
return false;
357-
Ty = StructTy->elements().front();
358-
} else if (ArrayType *ArrayTy = dyn_cast<ArrayType>(Ty)) {
359-
do {
360-
Ty = ArrayTy->getElementType();
361-
} while ((ArrayTy = dyn_cast<ArrayType>(Ty)));
362-
}
363-
return Ty->isFPOrFPVectorTy();
368+
return isSupportedFloatingPointType(V->getType());
364369
}
365370
default:
366371
return false;

llvm/lib/IR/Attributes.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/IR/ConstantRangeList.h"
2929
#include "llvm/IR/Function.h"
3030
#include "llvm/IR/LLVMContext.h"
31+
#include "llvm/IR/Operator.h"
3132
#include "llvm/IR/Type.h"
3233
#include "llvm/Support/Compiler.h"
3334
#include "llvm/Support/ErrorHandling.h"
@@ -2094,9 +2095,7 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const {
20942095
///
20952096
/// TODO: Consider relaxing to any FP type struct fields.
20962097
bool AttributeFuncs::isNoFPClassCompatibleType(Type *Ty) {
2097-
while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
2098-
Ty = ArrTy->getElementType();
2099-
return Ty->isFPOrFPVectorTy();
2098+
return FPMathOperator::isSupportedFloatingPointType(Ty);
21002099
}
21012100

21022101
/// Which attributes cannot be applied to a type.

llvm/test/Bitcode/compatibility.ll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2097,9 +2097,14 @@ declare nofpclass(sub zero) float @nofpclass_sub_zero(float nofpclass(sub zero))
20972097
; CHECK: declare nofpclass(inf sub) float @nofpclass_sub_inf(float nofpclass(inf sub))
20982098
declare nofpclass(sub inf) float @nofpclass_sub_inf(float nofpclass(sub inf))
20992099

2100+
; CHECK: declare nofpclass(nan) { float, float } @nofpclass_struct({ double } nofpclass(nan))
2101+
declare nofpclass(nan) { float, float } @nofpclass_struct({ double } nofpclass(nan))
2102+
21002103
declare float @unknown_fpclass_func(float)
21012104

2102-
define float @nofpclass_callsites(float %arg) {
2105+
declare { <4 x double>, <4 x double>, <4 x double> } @unknown_fpclass_struct_func({ float })
2106+
2107+
define float @nofpclass_callsites(float %arg, { float } %arg1) {
21032108
; CHECK: %call0 = call nofpclass(nan) float @unknown_fpclass_func(float nofpclass(ninf) %arg)
21042109
%call0 = call nofpclass(nan) float @unknown_fpclass_func(float nofpclass(ninf) %arg)
21052110

@@ -2108,6 +2113,10 @@ define float @nofpclass_callsites(float %arg) {
21082113

21092114
; CHECK: %call2 = call nofpclass(zero) float @unknown_fpclass_func(float nofpclass(norm) %arg)
21102115
%call2 = call nofpclass(zero) float @unknown_fpclass_func(float nofpclass(norm) %arg)
2116+
2117+
; CHECK: %call3 = call nofpclass(pinf) { <4 x double>, <4 x double>, <4 x double> } @unknown_fpclass_struct_func({ float } nofpclass(all) %arg1)
2118+
%call3 = call nofpclass(pinf) { <4 x double>, <4 x double>, <4 x double> } @unknown_fpclass_struct_func({ float } nofpclass(all) %arg1)
2119+
21112120
%add0 = fadd float %call0, %call1
21122121
%add1 = fadd float %add0, %call2
21132122
ret float %add1

0 commit comments

Comments
 (0)