Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4362,11 +4362,51 @@ break; } case Instruction::Select: { + Value *Cond = Op->getOperand(0); + Value *LHS = Op->getOperand(1); + Value *RHS = Op->getOperand(2); + + FPClassTest FilterLHS = fcAllFlags; + FPClassTest FilterRHS = fcAllFlags; + + Value *TestedValue = nullptr; + FPClassTest TestedMask = fcNone; + uint64_t ClassVal = 0; + const Function *F = cast(Op)->getFunction(); + CmpInst::Predicate Pred; + Value *CmpLHS, *CmpRHS; + if (F && match(Cond, m_FCmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)))) { + // If the select filters out a value based on the class, it no longer + // participates in the class of the result + + // TODO: In some degenerate cases we can infer something if we try gain + // without looking through sign operations. + bool LookThroughFAbsFNeg = CmpLHS != LHS && CmpLHS != RHS; + std::tie(TestedValue, TestedMask) = + fcmpToClassTest(Pred, *F, CmpLHS, CmpRHS, LookThroughFAbsFNeg); + } else if (match(Cond, + m_Intrinsic( + m_Value(TestedValue), m_ConstantInt(ClassVal)))) { + TestedMask = static_cast(ClassVal); + } + + if (TestedValue == LHS) { + // match !isnan(x) ? x : y + FilterLHS = TestedMask; + } else if (TestedValue == RHS) { + // match !isnan(x) ? y : x + FilterRHS = ~TestedMask; + } + KnownFPClass Known2; - computeKnownFPClass(Op->getOperand(1), DemandedElts, InterestedClasses, - Known, Depth + 1, Q); - computeKnownFPClass(Op->getOperand(2), DemandedElts, InterestedClasses, + computeKnownFPClass(LHS, DemandedElts, InterestedClasses & FilterLHS, Known, + Depth + 1, Q); + Known.KnownFPClasses &= FilterLHS; + + computeKnownFPClass(RHS, DemandedElts, InterestedClasses & FilterRHS, Known2, Depth + 1, Q); + Known2.KnownFPClasses &= FilterRHS; + Known |= Known2; break; } Index: llvm/test/Transforms/Attributor/nofpclass-select.ll =================================================================== --- llvm/test/Transforms/Attributor/nofpclass-select.ll +++ llvm/test/Transforms/Attributor/nofpclass-select.ll @@ -69,11 +69,11 @@ ; Clamp nan to 0 pattern define float @ret_select_clamp_nan_to_zero_uno(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_nan_to_zero_uno +; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_uno ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_NAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.nan = fcmp uno float %arg, 0.0 @@ -83,11 +83,11 @@ } define float @ret_select_clamp_nan_to_zero_ord(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_nan_to_zero_ord +; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_ord ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[NOT_NAN]], float [[ARG]], float 0.000000e+00 -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %not.nan = fcmp ord float %arg, 0.0 @@ -97,11 +97,11 @@ } define float @ret_select_clamp_onlynans(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_onlynans +; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_select_clamp_onlynans ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[NOT_NAN]], float 0x7FF8000000000000, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(inf zero sub norm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %not.nan = fcmp ord float %arg, 0.0 @@ -111,12 +111,12 @@ } define float @clamp_nonfinite_to_normal_olt(float %arg) { -; CHECK-LABEL: define float @clamp_nonfinite_to_normal_olt +; CHECK-LABEL: define nofpclass(nan inf) float @clamp_nonfinite_to_normal_olt ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt float [[FABS]], 0x7FF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_FINITE]], float [[ARG]], float 1.024000e+03 -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan inf) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -127,12 +127,12 @@ } define float @clamp_eq_inf_to_pnormal(float %arg) { -; CHECK-LABEL: define float @clamp_eq_inf_to_pnormal +; CHECK-LABEL: define nofpclass(inf) float @clamp_eq_inf_to_pnormal ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_INF]], float 1.024000e+03, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(inf) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -143,11 +143,11 @@ } define float @clamp_eq_pinf_to_pnormal(float %arg) { -; CHECK-LABEL: define float @clamp_eq_pinf_to_pnormal +; CHECK-LABEL: define nofpclass(pinf) float @clamp_eq_pinf_to_pnormal ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_INF:%.*]] = fcmp oeq float [[ARG]], 0x7FF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_INF]], float 1.024000e+03, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(pinf) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.inf = fcmp oeq float %arg, 0x7FF0000000000000 @@ -157,11 +157,11 @@ } define float @clamp_eq_ninf_to_negnormal(float %arg) { -; CHECK-LABEL: define float @clamp_eq_ninf_to_negnormal +; CHECK-LABEL: define nofpclass(ninf) float @clamp_eq_ninf_to_negnormal ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_INF:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_INF]], float -1.024000e+03, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(ninf) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.inf = fcmp oeq float %arg, 0xFFF0000000000000 @@ -171,12 +171,12 @@ } define float @clamp_eq_inf_to_nan(float %arg) { -; CHECK-LABEL: define float @clamp_eq_inf_to_nan +; CHECK-LABEL: define nofpclass(inf) float @clamp_eq_inf_to_nan ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_INF]], float 0x7FF8000000000000, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(inf) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -201,12 +201,12 @@ } define float @isfinite_select_fabs_val_0(float %arg) { -; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @isfinite_select_fabs_val_0 +; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @isfinite_select_fabs_val_0 ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt float [[FABS]], 0x7FF0000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_FINITE]], float [[FABS]], float 1.024000e+03 -; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -217,12 +217,12 @@ } define float @isfinite_select_fabs_val_1(float %arg) { -; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @isfinite_select_fabs_val_1 +; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @isfinite_select_fabs_val_1 ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[NOT_IS_FINITE:%.*]] = fcmp uge float [[FABS]], 0x3810000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[NOT_IS_FINITE]], float 1.024000e+03, float [[FABS]] -; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan inf nzero nsub nnorm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -233,12 +233,12 @@ } define float @clamp_denormal_to_poszero(float %arg) { -; CHECK-LABEL: define float @clamp_denormal_to_poszero +; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_denormal_to_poszero ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float 0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nzero sub) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -249,12 +249,12 @@ } define float @clamp_denormal_to_negzero(float %arg) { -; CHECK-LABEL: define float @clamp_denormal_to_negzero +; CHECK-LABEL: define nofpclass(pzero sub) float @clamp_denormal_to_negzero ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float -0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(pzero sub) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -265,13 +265,13 @@ } define float @clamp_denormal_to_zero_copysign(float %arg) { -; CHECK-LABEL: define float @clamp_denormal_to_zero_copysign +; CHECK-LABEL: define nofpclass(sub) float @clamp_denormal_to_zero_copysign ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000 ; CHECK-NEXT: [[ZERO:%.*]] = call float @llvm.copysign.f32(float noundef 0.000000e+00, float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[ZERO]], float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(sub) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -283,12 +283,12 @@ } define float @clamp_only_denormal_or_zero(float %arg) { -; CHECK-LABEL: define float @clamp_only_denormal_or_zero +; CHECK-LABEL: define nofpclass(nan inf norm) float @clamp_only_denormal_or_zero ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]] ; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[ARG]], float 0.000000e+00 -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan inf norm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %fabs = call float @llvm.fabs.f32(float %arg) @@ -331,11 +331,11 @@ } define float @clamp_zero_to_inf(float %arg) { -; CHECK-LABEL: define float @clamp_zero_to_inf +; CHECK-LABEL: define nofpclass(zero) float @clamp_zero_to_inf ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_ZERO]], float 0x7FF0000000000000, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(zero) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.zero = fcmp oeq float %arg, 0.0 @@ -345,11 +345,11 @@ } define float @clamp_zero_to_only_inf(float %arg) { -; CHECK-LABEL: define float @clamp_zero_to_only_inf +; CHECK-LABEL: define nofpclass(nan ninf sub norm) float @clamp_zero_to_only_inf ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00 ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_ZERO]], float [[ARG]], float 0x7FF0000000000000 -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan ninf sub norm) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.zero = fcmp oeq float %arg, 0.0 @@ -359,11 +359,11 @@ } define float @clamp_is_class_subnormal_or_inf_to_nan(float %arg) { -; CHECK-LABEL: define float @clamp_is_class_subnormal_or_inf_to_nan +; CHECK-LABEL: define nofpclass(inf sub) float @clamp_is_class_subnormal_or_inf_to_nan ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_SUBNORMAL_OR_INF:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 660) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_SUBNORMAL_OR_INF]], float 0x7FF8000000000000, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(inf sub) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.subnormal.or.inf = call i1 @llvm.is.fpclass.f32(float %arg, i32 660) @@ -373,11 +373,11 @@ } define float @clamp_is_class_subnormal_or_inf_to_nan_swap(float %arg) { -; CHECK-LABEL: define float @clamp_is_class_subnormal_or_inf_to_nan_swap +; CHECK-LABEL: define nofpclass(inf sub) float @clamp_is_class_subnormal_or_inf_to_nan_swap ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[NOT_IS_SUBNORMAL_OR_INF:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 363) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[NOT_IS_SUBNORMAL_OR_INF]], float [[ARG]], float 0x7FF8000000000000 -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(inf sub) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %not.is.subnormal.or.inf = call i1 @llvm.is.fpclass.f32(float %arg, i32 363) @@ -387,11 +387,11 @@ } define float @ret_select_clamp_nan_to_zero_fpclass(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_nan_to_zero_fpclass +; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_fpclass ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 3) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 3) @@ -401,11 +401,11 @@ } define float @ret_select_clamp_snan_to_zero_fpclass(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_snan_to_zero_fpclass +; CHECK-LABEL: define nofpclass(snan) float @ret_select_clamp_snan_to_zero_fpclass ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 1) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(snan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 1) @@ -415,11 +415,11 @@ } define float @ret_select_clamp_qnan_to_zero_fpclass(float %arg) { -; CHECK-LABEL: define float @ret_select_clamp_qnan_to_zero_fpclass +; CHECK-LABEL: define nofpclass(qnan) float @ret_select_clamp_qnan_to_zero_fpclass ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 2) #[[ATTR2]] ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]] -; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] +; CHECK-NEXT: [[FENCE:%.*]] = call nofpclass(qnan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[FENCE]] ; %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 2)