1 //===- ReduceOpcodes.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 #include "ReduceMemoryOperations.h" 10 #include "Delta.h" 11 #include "llvm/IR/InstIterator.h" 12 #include "llvm/IR/Instructions.h" 13 #include "llvm/IR/IntrinsicInst.h" 14 15 static void removeVolatileInFunction(Oracle &O, Function &F) { 16 LLVMContext &Ctx = F.getContext(); 17 for (Instruction &I : instructions(F)) { 18 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { 19 if (LI->isVolatile() && !O.shouldKeep()) 20 LI->setVolatile(false); 21 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { 22 if (SI->isVolatile() && !O.shouldKeep()) 23 SI->setVolatile(false); 24 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { 25 if (RMW->isVolatile() && !O.shouldKeep()) 26 RMW->setVolatile(false); 27 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { 28 if (CmpXChg->isVolatile() && !O.shouldKeep()) 29 CmpXChg->setVolatile(false); 30 } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) { 31 if (MemIntrin->isVolatile() && !O.shouldKeep()) 32 MemIntrin->setVolatile(ConstantInt::getFalse(Ctx)); 33 } 34 } 35 } 36 37 static void removeVolatileInModule(Oracle &O, ReducerWorkItem &WorkItem) { 38 for (Function &F : WorkItem.getModule()) 39 removeVolatileInFunction(O, F); 40 } 41 42 void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) { 43 runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions"); 44 } 45 46 static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) { 47 for (Instruction &I : instructions(F)) { 48 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { 49 if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) 50 LI->setSyncScopeID(SyncScope::System); 51 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { 52 if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) 53 SI->setSyncScopeID(SyncScope::System); 54 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { 55 if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) 56 RMW->setSyncScopeID(SyncScope::System); 57 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { 58 if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) 59 CmpXChg->setSyncScopeID(SyncScope::System); 60 } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) { 61 if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) 62 Fence->setSyncScopeID(SyncScope::System); 63 } 64 } 65 } 66 67 static void reduceAtomicSyncScopesInModule(Oracle &O, 68 ReducerWorkItem &WorkItem) { 69 for (Function &F : WorkItem.getModule()) 70 reduceAtomicSyncScopesInFunction(O, F); 71 } 72 73 void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) { 74 runDeltaPass(Test, reduceAtomicSyncScopesInModule, 75 "Reducing Atomic Sync Scopes"); 76 } 77 78 // TODO: Might be helpful to incrementally relax orders 79 static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) { 80 for (Instruction &I : instructions(F)) { 81 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { 82 if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep()) 83 LI->setAtomic(AtomicOrdering::NotAtomic); 84 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { 85 if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep()) 86 SI->setAtomic(AtomicOrdering::NotAtomic); 87 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { 88 if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep()) 89 RMW->setOrdering(AtomicOrdering::Monotonic); 90 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { 91 if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic && 92 !O.shouldKeep()) 93 CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic); 94 if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic && 95 !O.shouldKeep()) 96 CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic); 97 } 98 } 99 } 100 101 static void reduceAtomicOrderingInModule(Oracle &O, ReducerWorkItem &WorkItem) { 102 for (Function &F : WorkItem.getModule()) 103 reduceAtomicOrderingInFunction(O, F); 104 } 105 106 void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) { 107 runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Ordering"); 108 } 109