Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4488,6 +4488,16 @@ Known.knownNot(fcNan); break; } + case Intrinsic::minimum: + case Intrinsic::maximum: { + KnownFPClass Known2; + computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses, + Known, Depth + 1, Q, TLI); + computeKnownFPClass(II->getArgOperand(1), DemandedElts, InterestedClasses, + Known2, Depth + 1, Q, TLI); + Known |= Known2; + break; + } case Intrinsic::canonicalize: { computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses, Known, Depth + 1, Q, TLI); Index: llvm/test/Transforms/Attributor/nofpclass-minimum-maximum.ll =================================================================== --- llvm/test/Transforms/Attributor/nofpclass-minimum-maximum.ll +++ llvm/test/Transforms/Attributor/nofpclass-minimum-maximum.ll @@ -15,9 +15,9 @@ } define float @ret_minimum_noinf__noinf(float nofpclass(inf) %arg0, float nofpclass(inf) %arg1) { -; CHECK-LABEL: define float @ret_minimum_noinf__noinf +; CHECK-LABEL: define nofpclass(inf) float @ret_minimum_noinf__noinf ; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.minimum.f32(float %arg0, float %arg1) @@ -45,9 +45,9 @@ } define float @ret_minimum_noinf_nonan__nonan(float nofpclass(inf nan) %arg0, float nofpclass(nan) %arg1) { -; CHECK-LABEL: define float @ret_minimum_noinf_nonan__nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_minimum_noinf_nonan__nonan ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.minimum.f32(float %arg0, float %arg1) @@ -55,9 +55,9 @@ } define float @ret_minimum_nonan__noinf_nonan(float nofpclass(nan) %arg0, float nofpclass(inf nan) %arg1) { -; CHECK-LABEL: define float @ret_minimum_nonan__noinf_nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_minimum_nonan__noinf_nonan ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.minimum.f32(float %arg0, float %arg1) @@ -65,9 +65,9 @@ } define float @ret_minimum_norm_zero__norm_sub(float nofpclass(norm zero) %arg0, float nofpclass(norm sub) %arg1) { -; CHECK-LABEL: define float @ret_minimum_norm_zero__norm_sub +; CHECK-LABEL: define nofpclass(norm) float @ret_minimum_norm_zero__norm_sub ; CHECK-SAME: (float nofpclass(zero norm) [[ARG0:%.*]], float nofpclass(sub norm) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(norm) float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.minimum.f32(float %arg0, float %arg1) @@ -85,9 +85,9 @@ } define float @ret_maximum_noinf__noinf(float nofpclass(inf) %arg0, float nofpclass(inf) %arg1) { -; CHECK-LABEL: define float @ret_maximum_noinf__noinf +; CHECK-LABEL: define nofpclass(inf) float @ret_maximum_noinf__noinf ; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(inf) float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.maximum.f32(float %arg0, float %arg1) @@ -115,9 +115,9 @@ } define float @ret_maximum_noinf_nonan__nonan(float nofpclass(inf nan) %arg0, float nofpclass(nan) %arg1) { -; CHECK-LABEL: define float @ret_maximum_noinf_nonan__nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_maximum_noinf_nonan__nonan ; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.maximum.f32(float %arg0, float %arg1) @@ -125,9 +125,9 @@ } define float @ret_maximum_nonan__noinf_nonan(float nofpclass(nan) %arg0, float nofpclass(inf nan) %arg1) { -; CHECK-LABEL: define float @ret_maximum_nonan__noinf_nonan +; CHECK-LABEL: define nofpclass(nan) float @ret_maximum_nonan__noinf_nonan ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.maximum.f32(float %arg0, float %arg1) @@ -135,9 +135,9 @@ } define float @ret_maximum_norm_zero__norm_sub(float nofpclass(norm zero) %arg0, float nofpclass(norm sub) %arg1) { -; CHECK-LABEL: define float @ret_maximum_norm_zero__norm_sub +; CHECK-LABEL: define nofpclass(norm) float @ret_maximum_norm_zero__norm_sub ; CHECK-SAME: (float nofpclass(zero norm) [[ARG0:%.*]], float nofpclass(sub norm) [[ARG1:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(norm) float @llvm.maximum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR2]] ; CHECK-NEXT: ret float [[CALL]] ; %call = call float @llvm.maximum.f32(float %arg0, float %arg1)