1//===- ReduceInstructionFlags.cpp - Specialized Delta Pass ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Try to remove optimization flags on instructions
10//
11//===----------------------------------------------------------------------===//
12
13#include "ReduceInstructionFlags.h"
14#include "Delta.h"
15#include "llvm/IR/InstIterator.h"
16#include "llvm/IR/Instruction.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/Operator.h"
19
20using namespace llvm;
21
22static void reduceFlagsInModule(Oracle &O, ReducerWorkItem &WorkItem) {
23 for (Function &F : WorkItem.getModule()) {
24 for (Instruction &I : instructions(F)) {
25 if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(Val: &I)) {
26 if (OBO->hasNoSignedWrap() && !O.shouldKeep())
27 I.setHasNoSignedWrap(false);
28 if (OBO->hasNoUnsignedWrap() && !O.shouldKeep())
29 I.setHasNoUnsignedWrap(false);
30 } else if (auto *Trunc = dyn_cast<TruncInst>(Val: &I)) {
31 if (Trunc->hasNoSignedWrap() && !O.shouldKeep())
32 Trunc->setHasNoSignedWrap(false);
33 if (Trunc->hasNoUnsignedWrap() && !O.shouldKeep())
34 Trunc->setHasNoUnsignedWrap(false);
35 } else if (auto *PE = dyn_cast<PossiblyExactOperator>(Val: &I)) {
36 if (PE->isExact() && !O.shouldKeep())
37 I.setIsExact(false);
38 } else if (auto *NNI = dyn_cast<PossiblyNonNegInst>(Val: &I)) {
39 if (NNI->hasNonNeg() && !O.shouldKeep())
40 NNI->setNonNeg(false);
41 } else if (auto *PDI = dyn_cast<PossiblyDisjointInst>(Val: &I)) {
42 if (PDI->isDisjoint() && !O.shouldKeep())
43 PDI->setIsDisjoint(false);
44 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(Val: &I)) {
45 GEPNoWrapFlags NW = GEP->getNoWrapFlags();
46 if (NW.isInBounds() && !O.shouldKeep())
47 NW = NW.withoutInBounds();
48 if (NW.hasNoUnsignedSignedWrap() && !O.shouldKeep())
49 NW = NW.withoutNoUnsignedSignedWrap();
50 if (NW.hasNoUnsignedWrap() && !O.shouldKeep())
51 NW = NW.withoutNoUnsignedWrap();
52 GEP->setNoWrapFlags(NW);
53 } else if (auto *FPOp = dyn_cast<FPMathOperator>(Val: &I)) {
54 FastMathFlags Flags = FPOp->getFastMathFlags();
55
56 if (Flags.allowReassoc() && !O.shouldKeep())
57 Flags.setAllowReassoc(false);
58
59 if (Flags.noNaNs() && !O.shouldKeep())
60 Flags.setNoNaNs(false);
61
62 if (Flags.noInfs() && !O.shouldKeep())
63 Flags.setNoInfs(false);
64
65 if (Flags.noSignedZeros() && !O.shouldKeep())
66 Flags.setNoSignedZeros(false);
67
68 if (Flags.allowReciprocal() && !O.shouldKeep())
69 Flags.setAllowReciprocal(false);
70
71 if (Flags.allowContract() && !O.shouldKeep())
72 Flags.setAllowContract(false);
73
74 if (Flags.approxFunc() && !O.shouldKeep())
75 Flags.setApproxFunc(false);
76
77 I.copyFastMathFlags(FMF: Flags);
78 }
79 }
80 }
81}
82
83void llvm::reduceInstructionFlagsDeltaPass(TestRunner &Test) {
84 runDeltaPass(Test, ExtractChunksFromModule: reduceFlagsInModule, Message: "Reducing Instruction Flags");
85}
86