Index: llvm/test/tools/llvm-reduce/reduce-flags.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/reduce-flags.ll @@ -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: llvm/tools/llvm-reduce/CMakeLists.txt =================================================================== --- llvm/tools/llvm-reduce/CMakeLists.txt +++ llvm/tools/llvm-reduce/CMakeLists.txt @@ -36,6 +36,7 @@ deltas/ReduceGlobalVarInitializers.cpp deltas/ReduceGlobalVars.cpp deltas/ReduceInstructions.cpp + deltas/ReduceInstructionFlags.cpp deltas/ReduceMetadata.cpp deltas/ReduceModuleData.cpp deltas/ReduceOperandBundles.cpp Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -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" @@ -94,7 +95,8 @@ 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 { \ Index: llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.h =================================================================== --- /dev/null +++ llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.h @@ -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 Index: llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.cpp =================================================================== --- /dev/null +++ llvm/tools/llvm-reduce/deltas/ReduceInstructionFlags.cpp @@ -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(&I)) { + if (OBO->hasNoSignedWrap() && !O.shouldKeep()) + I.setHasNoSignedWrap(false); + if (OBO->hasNoUnsignedWrap() && !O.shouldKeep()) + I.setHasNoUnsignedWrap(false); + } else if (auto *PE = dyn_cast(&I)) { + if (PE->isExact() && !O.shouldKeep()) + I.setIsExact(false); + } else if (auto *GEP = dyn_cast(&I)) { + if (GEP->isInBounds() && !O.shouldKeep()) + GEP->setIsInBounds(false); + } else if (auto *FPOp = dyn_cast(&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"); +}