From d5b7514c3d298058d2509af5e0093519b1a20662 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 3 Jan 2023 08:00:03 -0500 Subject: [PATCH] llvm-reduce: Don't remove strictfp The verifier should fail if constrained intrinsics are used in functions with strictfp, but that patch hasn't been pushed yet. Ideally we would be able to analyze the function body to see if any constrained intrinsics were used, but we seem to be missing a utility function to check for any constrained ops. --- .../llvm-reduce/remove-attributes-strictfp.ll | 48 ++++++++++++++++++++++ llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp | 7 ++++ 2 files changed, 55 insertions(+) create mode 100644 llvm/test/tools/llvm-reduce/remove-attributes-strictfp.ll diff --git a/llvm/test/tools/llvm-reduce/remove-attributes-strictfp.ll b/llvm/test/tools/llvm-reduce/remove-attributes-strictfp.ll new file mode 100644 index 0000000..8607aae --- /dev/null +++ b/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) } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp index 5650367..0bd16ff 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp @@ -119,6 +119,13 @@ public: 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.emplace_back(A); + continue; + } } if (O.shouldKeep()) -- 2.7.4