llvm-reduce: Add flag reduction pass
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 21 Oct 2022 17:37:52 +0000 (10:37 -0700)
committerMatt Arsenault <arsenm2@gmail.com>
Sun, 23 Oct 2022 22:16:54 +0000 (15:16 -0700)
Try to remove each flag from instructions. It may make more
sense to introduce these flags instead.

llvm/test/tools/llvm-reduce/reduce-flags.ll [new file with mode: 0644]
llvm/tools/llvm-reduce/CMakeLists.txt
llvm/tools/llvm-reduce/DeltaManager.cpp
llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.cpp [new file with mode: 0644]
llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.h [new file with mode: 0644]

diff --git a/llvm/test/tools/llvm-reduce/reduce-flags.ll b/llvm/test/tools/llvm-reduce/reduce-flags.ll
new file mode 100644 (file)
index 0000000..4745f98
--- /dev/null
@@ -0,0 +1,202 @@
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=instruction-flags --test FileCheck --test-arg --check-prefixes=INTERESTING,CHECK --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck -check-prefixes=RESULT,CHECK %s < %t
+
+; CHECK-LABEL: @add_nuw_nsw_none(
+; INTERESTING: = add
+; RESULT: add i32
+define i32 @add_nuw_nsw_none(i32 %a, i32 %b) {
+  %op = add nuw nsw i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @add_nuw_nsw_keep_nuw(
+; INTERESTING: nuw
+; RESULT: add nuw i32
+define i32 @add_nuw_nsw_keep_nuw(i32 %a, i32 %b) {
+  %op = add nuw nsw i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @add_nuw_nsw_keep_nsw(
+; INTERESTING: nuw
+; RESULT: add nuw i32
+define i32 @add_nuw_nsw_keep_nsw(i32 %a, i32 %b) {
+  %op = add nuw nsw i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @add_nuw_keep_nuw(
+; INTERESTING: nuw
+; RESULT: add nuw i32
+define i32 @add_nuw_keep_nuw(i32 %a, i32 %b) {
+  %op = add nuw i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @add_nsw_keep_nsw(
+; INTERESTING: nsw
+; RESULT: add nsw i32
+define i32 @add_nsw_keep_nsw(i32 %a, i32 %b) {
+  %op = add nsw i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @ashr_exact_drop(
+; INTERESTING: = ashr
+; RESULT: ashr i32
+define i32 @ashr_exact_drop(i32 %a, i32 %b) {
+  %op = ashr exact i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @ashr_exact_keep(
+; INTERESTING: exact
+; RESULT: ashr exact i32
+define i32 @ashr_exact_keep(i32 %a, i32 %b) {
+  %op = ashr exact i32 %a, %b
+  ret i32 %op
+}
+
+; CHECK-LABEL: @getelementptr_inbounds_drop(
+; INTERESTING: getelementptr
+; RESULT: getelementptr i32, ptr %a, i64 %b
+define ptr @getelementptr_inbounds_drop(ptr %a, i64 %b) {
+  %op = getelementptr inbounds i32, ptr %a, i64 %b
+  ret ptr %op
+}
+
+; CHECK-LABEL: @getelementptr_inbounds_keep(
+; INTERESTING: inbounds
+; RESULT: getelementptr inbounds i32, ptr %a, i64 %b
+define ptr @getelementptr_inbounds_keep(ptr %a, i64 %b) {
+  %op = getelementptr inbounds i32, ptr %a, i64 %b
+  ret ptr %op
+}
+
+; CHECK-LABEL: @fadd_reassoc_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_reassoc_none(float %a, float %b) {
+  %op = fadd reassoc float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_reassoc_keep(
+; INTERESTING: fadd reassoc
+; RESULT: fadd reassoc float
+define float @fadd_reassoc_keep(float %a, float %b) {
+  %op = fadd reassoc float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_nnan_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_nnan_none(float %a, float %b) {
+  %op = fadd nnan float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_nnan_keep(
+; INTERESTING: fadd nnan
+; RESULT: fadd nnan float
+define float @fadd_nnan_keep(float %a, float %b) {
+  %op = fadd nnan float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_ninf_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_ninf_none(float %a, float %b) {
+  %op = fadd ninf float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_ninf_keep(
+; INTERESTING: fadd ninf
+; RESULT: fadd ninf float
+define float @fadd_ninf_keep(float %a, float %b) {
+  %op = fadd ninf float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_nsz_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_nsz_none(float %a, float %b) {
+  %op = fadd nsz float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_nsz_keep(
+; INTERESTING: fadd nsz
+; RESULT: fadd nsz float
+define float @fadd_nsz_keep(float %a, float %b) {
+  %op = fadd nsz float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_arcp_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_arcp_none(float %a, float %b) {
+  %op = fadd arcp float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_arcp_keep(
+; INTERESTING: fadd arcp
+; RESULT: fadd arcp float
+define float @fadd_arcp_keep(float %a, float %b) {
+  %op = fadd arcp float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_contract_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_contract_none(float %a, float %b) {
+  %op = fadd contract float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_contract_keep(
+; INTERESTING: fadd contract
+; RESULT: fadd contract float
+define float @fadd_contract_keep(float %a, float %b) {
+  %op = fadd contract float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_afn_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_afn_none(float %a, float %b) {
+  %op = fadd afn float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_afn_keep(
+; INTERESTING: fadd afn
+; RESULT: fadd afn float
+define float @fadd_afn_keep(float %a, float %b) {
+  %op = fadd afn float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_fast_none(
+; INTERESTING: = fadd
+; RESULT: fadd float
+define float @fadd_fast_none(float %a, float %b) {
+  %op = fadd fast float %a, %b
+  ret float %op
+}
+
+; CHECK-LABEL: @fadd_nnan_ninf_keep_nnan(
+; INTERESTING: nnan
+; RESULT: fadd nnan float
+define float @fadd_nnan_ninf_keep_nnan(float %a, float %b) {
+  %op = fadd nnan ninf float %a, %b
+  ret float %op
+}
index f6b485d..f539449 100644 (file)
@@ -36,6 +36,7 @@ add_llvm_tool(llvm-reduce
   deltas/ReduceGlobalVarInitializers.cpp
   deltas/ReduceGlobalVars.cpp
   deltas/ReduceInstructions.cpp
+  deltas/ReduceInstructionFlags.cpp
   deltas/ReduceMetadata.cpp
   deltas/ReduceModuleData.cpp
   deltas/ReduceOperandBundles.cpp
index f6b309d..dc9a583 100644 (file)
@@ -27,6 +27,7 @@
 #include "deltas/ReduceGlobalVarInitializers.h"
 #include "deltas/ReduceGlobalVars.h"
 #include "deltas/ReduceIRReferences.h"
+#include "deltas/ReduceInstructionFlags.h"
 #include "deltas/ReduceInstructionFlagsMIR.h"
 #include "deltas/ReduceInstructions.h"
 #include "deltas/ReduceInstructionsMIR.h"
@@ -93,7 +94,8 @@ static cl::list<std::string>
     DELTA_PASS("attributes", reduceAttributesDeltaPass)                        \
     DELTA_PASS("module-data", reduceModuleDataDeltaPass)                       \
     DELTA_PASS("opcodes", reduceOpcodesDeltaPass)                              \
-  } while (false)
+    DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass)           \
+} while (false)
 
 #define DELTA_PASSES_MIR                                                       \
   do {                                                                         \
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.cpp
new file mode 100644 (file)
index 0000000..78bbaf9
--- /dev/null
@@ -0,0 +1,66 @@
+//===- ReduceInstructionFlags.cpp - Specialized Delta Pass ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Try to remove optimization flags on instructions
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceInstructionFlags.h"
+#include "Delta.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Operator.h"
+
+static void reduceFlagsInModule(Oracle &O, Module &Mod) {
+  for (Function &F : Mod) {
+    for (Instruction &I : instructions(F)) {
+      if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I)) {
+        if (OBO->hasNoSignedWrap() && !O.shouldKeep())
+          I.setHasNoSignedWrap(false);
+        if (OBO->hasNoUnsignedWrap() && !O.shouldKeep())
+          I.setHasNoUnsignedWrap(false);
+      } else if (auto *PE = dyn_cast<PossiblyExactOperator>(&I)) {
+        if (PE->isExact() && !O.shouldKeep())
+          I.setIsExact(false);
+      } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
+        if (GEP->isInBounds() && !O.shouldKeep())
+          GEP->setIsInBounds(false);
+      } else if (auto *FPOp = dyn_cast<FPMathOperator>(&I)) {
+        FastMathFlags Flags = FPOp->getFastMathFlags();
+
+        if (Flags.allowReassoc() && !O.shouldKeep())
+          Flags.setAllowReassoc(false);
+
+        if (Flags.noNaNs() && !O.shouldKeep())
+          Flags.setNoNaNs(false);
+
+        if (Flags.noInfs() && !O.shouldKeep())
+          Flags.setNoInfs(false);
+
+        if (Flags.noSignedZeros() && !O.shouldKeep())
+          Flags.setNoSignedZeros(false);
+
+        if (Flags.allowReciprocal() && !O.shouldKeep())
+          Flags.setAllowReciprocal(false);
+
+        if (Flags.allowContract() && !O.shouldKeep())
+          Flags.setAllowContract(false);
+
+        if (Flags.approxFunc() && !O.shouldKeep())
+          Flags.setApproxFunc(false);
+
+        I.copyFastMathFlags(Flags);
+      }
+    }
+  }
+}
+
+void llvm::reduceInstructionFlagsDeltaPass(TestRunner &Test) {
+  runDeltaPass(Test, reduceFlagsInModule, "Reducing Instruction Flags");
+}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.h b/llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.h
new file mode 100644 (file)
index 0000000..1764c01
--- /dev/null
@@ -0,0 +1,18 @@
+//===- ReduceInstructionFlags.h - Specialized Delta Pass --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEINSTRUCTIONFLAGS_H
+#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEINSTRUCTIONFLAGS_H
+
+#include "TestRunner.h"
+
+namespace llvm {
+void reduceInstructionFlagsDeltaPass(TestRunner &Test);
+} // namespace llvm
+
+#endif