Index: llvm/test/tools/llvm-reduce/remove-attributes-strictfp.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/remove-attributes-strictfp.ll @@ -0,0 +1,48 @@ +; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=attributes --test FileCheck --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefixes=CHECK,RESULT %s < %t + +; Test that invalid reductions aren't produced on strictfp functions. + +; CHECK-LABEL: define float @strictfp_intrinsic(float %x, float %y) +; RESULT-SAME: [[STRICTFP_ONLY:#[0-9]+]] { +define float @strictfp_intrinsic(float %x, float %y) #0 { + %val = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") + ret float %val +} + +; CHECK-LABEL: define float @strictfp_callsite(float %x, float %y) +; RESULT-SAME: [[STRICTFP_ONLY]] { +; RESULT: call float @extern.func(float %x, float %y) [[STRICTFP_ONLY]] +define float @strictfp_callsite(float %x, float %y) #0 { + %val = call float @extern.func(float %x, float %y) #0 + ret float %val +} + +; CHECK-LABEL: define float @strictfp_declaration(float %x, float %y) +; RESULT-SAME: [[STRICTFP_ONLY]] { +define float @strictfp_declaration(float %x, float %y) #0 { + %val = call float @strict.extern.func(float %x, float %y) + ret float %val +} + +; CHECK-LABEL: define float @strictfp_no_constrained_ops(float %x, float %y) +; RESULT-SAME: [[STRICTFP_ONLY]] { +define float @strictfp_no_constrained_ops(float %x, float %y) #0 { + %val = call float @llvm.copysign.f32(float %x, float %y) + ret float %val +} + +; CHECK-LABEL: declare float @strict.extern.func(float, float) +; RESULT-SAME: [[STRICTFP_ONLY]]{{$}} +declare float @strict.extern.func(float, float) #0 + +declare float @extern.func(float, float) + +declare float @llvm.copysign.f32(float, float) #1 +declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) #2 + +; RESULT: attributes [[STRICTFP_ONLY]] = { strictfp } + +attributes #0 = { nounwind strictfp } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #2 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } Index: llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp +++ llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp @@ -128,6 +128,13 @@ if (RemoveNoInline && Kind == Attribute::OptimizeNone) continue; + + // TODO: Could only remove this if there are no constrained calls in the + // function. + if (Kind == Attribute::StrictFP) { + AttrsToPreserve.addAttribute(A); + continue; + } } if (O.shouldKeep())