Skip to content

[Attributor][FIX] Replace AANoFPClass MBEC propagation #91030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion llvm/include/llvm/Transforms/IPO/Attributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5418,10 +5418,14 @@ struct AANoFPClass
return false;
}

/// Return true if we assume that the underlying value is nofpclass.
/// Return the underlying assumed nofpclass.
FPClassTest getAssumedNoFPClass() const {
return static_cast<FPClassTest>(getAssumed());
}
/// Return the underlying known nofpclass.
FPClassTest getKnownNoFPClass() const {
return static_cast<FPClassTest>(getKnown());
}

/// Create an abstract attribute view for the position \p IRP.
static AANoFPClass &createForPosition(const IRPosition &IRP, Attributor &A);
Expand Down
47 changes: 12 additions & 35 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10338,48 +10338,25 @@ struct AANoFPClassImpl : AANoFPClass {
/// See followUsesInMBEC
bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
AANoFPClass::StateType &State) {
const Value *UseV = U->get();
const DominatorTree *DT = nullptr;
AssumptionCache *AC = nullptr;
const TargetLibraryInfo *TLI = nullptr;
InformationCache &InfoCache = A.getInfoCache();

if (Function *F = getAnchorScope()) {
DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
}

const DataLayout &DL = A.getDataLayout();

KnownFPClass KnownFPClass =
computeKnownFPClass(UseV, DL,
/*InterestedClasses=*/fcAllFlags,
/*Depth=*/0, TLI, AC, I, DT);
State.addKnownBits(~KnownFPClass.KnownFPClasses);

if (auto *CI = dyn_cast<CallInst>(UseV)) {
// Special case FP intrinsic with struct return type.
switch (CI->getIntrinsicID()) {
case Intrinsic::frexp:
return true;
case Intrinsic::not_intrinsic:
// TODO: Could recognize math libcalls
return false;
default:
break;
}
}
// TODO: Determine what instructions can be looked through.
auto *CB = dyn_cast<CallBase>(I);
if (!CB)
return false;

if (!UseV->getType()->isFPOrFPVectorTy())
if (!CB->isArgOperand(U))
return false;
Comment on lines +10346 to 10347
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An FP type / vector couldn't be the arg operand so is this condition even possible?

Copy link
Member Author

@jdoerfert jdoerfert May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be a operand bundle entry, I believe.

return !isa<LoadInst, AtomicRMWInst>(UseV);

unsigned ArgNo = CB->getArgOperandNo(U);
IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
State.addKnownBits(NoFPAA->getState().getKnown());
return false;
}

const std::string getAsStr(Attributor *A) const override {
std::string Result = "nofpclass";
raw_string_ostream OS(Result);
OS << getAssumedNoFPClass();
OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
return Result;
}

Expand Down
20 changes: 10 additions & 10 deletions llvm/test/Transforms/Attributor/nofpclass-arithmetic-fence.ll
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ define float @ret_arithmetic.fence(float %arg0) {
define float @ret_arithmetic.fence_noinf(float nofpclass(inf) %arg0) {
; CHECK-LABEL: define nofpclass(inf) float @ret_arithmetic.fence_noinf
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) float @llvm.arithmetic.fence.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -26,7 +26,7 @@ define float @ret_arithmetic.fence_noinf(float nofpclass(inf) %arg0) {
define float @ret_arithmetic.fence_nopinf(float nofpclass(pinf) %arg0) {
; CHECK-LABEL: define nofpclass(pinf) float @ret_arithmetic.fence_nopinf
; CHECK-SAME: (float nofpclass(pinf) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pinf) float @llvm.arithmetic.fence.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -36,7 +36,7 @@ define float @ret_arithmetic.fence_nopinf(float nofpclass(pinf) %arg0) {
define float @ret_arithmetic.fence_noninf(float nofpclass(ninf) %arg0) {
; CHECK-LABEL: define nofpclass(ninf) float @ret_arithmetic.fence_noninf
; CHECK-SAME: (float nofpclass(ninf) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf) float @llvm.arithmetic.fence.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -46,7 +46,7 @@ define float @ret_arithmetic.fence_noninf(float nofpclass(ninf) %arg0) {
define float @ret_arithmetic.fence_nonan(float nofpclass(nan) %arg0) {
; CHECK-LABEL: define nofpclass(nan) float @ret_arithmetic.fence_nonan
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -56,7 +56,7 @@ define float @ret_arithmetic.fence_nonan(float nofpclass(nan) %arg0) {
define float @ret_arithmetic.fence_noqnan(float nofpclass(qnan) %arg0) {
; CHECK-LABEL: define nofpclass(qnan) float @ret_arithmetic.fence_noqnan
; CHECK-SAME: (float nofpclass(qnan) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(qnan) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(qnan) float @llvm.arithmetic.fence.f32(float nofpclass(qnan) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -66,7 +66,7 @@ define float @ret_arithmetic.fence_noqnan(float nofpclass(qnan) %arg0) {
define float @ret_arithmetic.fence_nosnan(float nofpclass(snan) %arg0) {
; CHECK-LABEL: define nofpclass(snan) float @ret_arithmetic.fence_nosnan
; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.arithmetic.fence.f32(float nofpclass(snan) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -76,7 +76,7 @@ define float @ret_arithmetic.fence_nosnan(float nofpclass(snan) %arg0) {
define float @ret_arithmetic.fence_nozero(float nofpclass(zero) %arg0) {
; CHECK-LABEL: define nofpclass(zero) float @ret_arithmetic.fence_nozero
; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(zero) float @llvm.arithmetic.fence.f32(float nofpclass(zero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -86,7 +86,7 @@ define float @ret_arithmetic.fence_nozero(float nofpclass(zero) %arg0) {
define float @ret_arithmetic.fence_nopzero(float nofpclass(pzero) %arg0) {
; CHECK-LABEL: define nofpclass(pzero) float @ret_arithmetic.fence_nopzero
; CHECK-SAME: (float nofpclass(pzero) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(pzero) float @llvm.arithmetic.fence.f32(float nofpclass(pzero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -96,7 +96,7 @@ define float @ret_arithmetic.fence_nopzero(float nofpclass(pzero) %arg0) {
define float @ret_arithmetic.fence_nonzero(float nofpclass(nzero) %arg0) {
; CHECK-LABEL: define nofpclass(nzero) float @ret_arithmetic.fence_nonzero
; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nzero) float @llvm.arithmetic.fence.f32(float nofpclass(nzero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand All @@ -106,7 +106,7 @@ define float @ret_arithmetic.fence_nonzero(float nofpclass(nzero) %arg0) {
define float @ret_arithmetic.fence_nonorm(float nofpclass(norm) %arg0) {
; CHECK-LABEL: define nofpclass(norm) float @ret_arithmetic.fence_nonorm
; CHECK-SAME: (float nofpclass(norm) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(norm) float @llvm.arithmetic.fence.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(norm) float @llvm.arithmetic.fence.f32(float nofpclass(norm) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.arithmetic.fence.f32(float %arg0)
Expand Down
38 changes: 19 additions & 19 deletions llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ declare float @llvm.canonicalize.f32(float)

define float @ret_canonicalize(float %arg0) {
; CHECK-LABEL: define nofpclass(snan) float @ret_canonicalize
; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12:[0-9]+]]
; CHECK-NEXT: ret float [[CALL]]
;
Expand All @@ -15,8 +15,8 @@ define float @ret_canonicalize(float %arg0) {

define float @ret_canonicalize_noinf(float nofpclass(inf) %arg0) {
; CHECK-LABEL: define nofpclass(snan inf) float @ret_canonicalize_noinf
; CHECK-SAME: (float nofpclass(snan inf) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -25,8 +25,8 @@ define float @ret_canonicalize_noinf(float nofpclass(inf) %arg0) {

define float @ret_canonicalize_dynamic_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="dynamic,dynamic" {
; CHECK-LABEL: define nofpclass(snan inf) float @ret_canonicalize_dynamic_denormal
; CHECK-SAME: (float nofpclass(snan inf) [[ARG0:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -35,8 +35,8 @@ define float @ret_canonicalize_dynamic_denormal(float nofpclass(inf) %arg0) "den

define float @ret_canonicalize_daz_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="dynamic,preserve-sign" {
; CHECK-LABEL: define nofpclass(snan inf sub) float @ret_canonicalize_daz_denormal
; CHECK-SAME: (float nofpclass(snan inf sub) [[ARG0:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -45,8 +45,8 @@ define float @ret_canonicalize_daz_denormal(float nofpclass(inf) %arg0) "denorma

define float @ret_canonicalize_dapz_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="dynamic,positive-zero" {
; CHECK-LABEL: define nofpclass(snan inf nzero sub) float @ret_canonicalize_dapz_denormal
; CHECK-SAME: (float nofpclass(snan inf nzero sub) [[ARG0:%.*]]) #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -55,8 +55,8 @@ define float @ret_canonicalize_dapz_denormal(float nofpclass(inf) %arg0) "denorm

define float @ret_canonicalize_ftpz_dapz_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="positive-zero,preserve-sign" {
; CHECK-LABEL: define nofpclass(snan inf sub) float @ret_canonicalize_ftpz_dapz_denormal
; CHECK-SAME: (float nofpclass(snan inf sub) [[ARG0:%.*]]) #[[ATTR5:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR5:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -65,8 +65,8 @@ define float @ret_canonicalize_ftpz_dapz_denormal(float nofpclass(inf) %arg0) "d

define float @ret_canonicalize_ftpz_ieee_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="positive-zero,ieee" {
; CHECK-LABEL: define nofpclass(snan inf nzero sub) float @ret_canonicalize_ftpz_ieee_denormal
; CHECK-SAME: (float nofpclass(snan inf nzero sub) [[ARG0:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf nzero sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -75,8 +75,8 @@ define float @ret_canonicalize_ftpz_ieee_denormal(float nofpclass(inf) %arg0) "d

define float @ret_canonicalize_ftpz_dynamic_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="positive-zero,dynamic" {
; CHECK-LABEL: define nofpclass(snan inf sub) float @ret_canonicalize_ftpz_dynamic_denormal
; CHECK-SAME: (float nofpclass(snan inf sub) [[ARG0:%.*]]) #[[ATTR7:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR7:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -85,8 +85,8 @@ define float @ret_canonicalize_ftpz_dynamic_denormal(float nofpclass(inf) %arg0)

define float @ret_canonicalize_ftz_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="preserve-sign,dynamic" {
; CHECK-LABEL: define nofpclass(snan inf sub) float @ret_canonicalize_ftz_denormal
; CHECK-SAME: (float nofpclass(snan inf sub) [[ARG0:%.*]]) #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf sub) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand All @@ -95,8 +95,8 @@ define float @ret_canonicalize_ftz_denormal(float nofpclass(inf) %arg0) "denorma

define float @ret_canonicalize_ieee_denormal(float nofpclass(inf) %arg0) "denormal-fp-math"="ieee,ieee" {
; CHECK-LABEL: define nofpclass(snan inf) float @ret_canonicalize_ieee_denormal
; CHECK-SAME: (float nofpclass(snan inf) [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float [[ARG0]]) #[[ATTR12]]
; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan inf) float @llvm.canonicalize.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %arg0)
Expand Down
Loading
Loading