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 20 using namespace llvm; 21 22 static void reduceFlagsInModule(Oracle &O, ReducerWorkItem &WorkItem) { 23 // Keep this in sync with computeIRComplexityScoreImpl(). 24 for (Function &F : WorkItem.getModule()) { 25 for (Instruction &I : instructions(F)) { 26 if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I)) { 27 if (OBO->hasNoSignedWrap() && !O.shouldKeep()) 28 I.setHasNoSignedWrap(false); 29 if (OBO->hasNoUnsignedWrap() && !O.shouldKeep()) 30 I.setHasNoUnsignedWrap(false); 31 } else if (auto *Trunc = dyn_cast<TruncInst>(&I)) { 32 if (Trunc->hasNoSignedWrap() && !O.shouldKeep()) 33 Trunc->setHasNoSignedWrap(false); 34 if (Trunc->hasNoUnsignedWrap() && !O.shouldKeep()) 35 Trunc->setHasNoUnsignedWrap(false); 36 } else if (auto *PE = dyn_cast<PossiblyExactOperator>(&I)) { 37 if (PE->isExact() && !O.shouldKeep()) 38 I.setIsExact(false); 39 } else if (auto *NNI = dyn_cast<PossiblyNonNegInst>(&I)) { 40 if (NNI->hasNonNeg() && !O.shouldKeep()) 41 NNI->setNonNeg(false); 42 } else if (auto *PDI = dyn_cast<PossiblyDisjointInst>(&I)) { 43 if (PDI->isDisjoint() && !O.shouldKeep()) 44 PDI->setIsDisjoint(false); 45 } else if (auto *ICmp = dyn_cast<ICmpInst>(&I)) { 46 if (ICmp->hasSameSign() && !O.shouldKeep()) 47 ICmp->setSameSign(false); 48 } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) { 49 GEPNoWrapFlags NW = GEP->getNoWrapFlags(); 50 if (NW.isInBounds() && !O.shouldKeep()) 51 NW = NW.withoutInBounds(); 52 if (NW.hasNoUnsignedSignedWrap() && !O.shouldKeep()) 53 NW = NW.withoutNoUnsignedSignedWrap(); 54 if (NW.hasNoUnsignedWrap() && !O.shouldKeep()) 55 NW = NW.withoutNoUnsignedWrap(); 56 GEP->setNoWrapFlags(NW); 57 } else if (auto *FPOp = dyn_cast<FPMathOperator>(&I)) { 58 FastMathFlags Flags = FPOp->getFastMathFlags(); 59 60 if (Flags.allowReassoc() && !O.shouldKeep()) 61 Flags.setAllowReassoc(false); 62 63 if (Flags.noNaNs() && !O.shouldKeep()) 64 Flags.setNoNaNs(false); 65 66 if (Flags.noInfs() && !O.shouldKeep()) 67 Flags.setNoInfs(false); 68 69 if (Flags.noSignedZeros() && !O.shouldKeep()) 70 Flags.setNoSignedZeros(false); 71 72 if (Flags.allowReciprocal() && !O.shouldKeep()) 73 Flags.setAllowReciprocal(false); 74 75 if (Flags.allowContract() && !O.shouldKeep()) 76 Flags.setAllowContract(false); 77 78 if (Flags.approxFunc() && !O.shouldKeep()) 79 Flags.setApproxFunc(false); 80 81 I.copyFastMathFlags(Flags); 82 } 83 } 84 } 85 } 86 87 void llvm::reduceInstructionFlagsDeltaPass(TestRunner &Test) { 88 runDeltaPass(Test, reduceFlagsInModule, "Reducing Instruction Flags"); 89 } 90