xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp (revision 333ffafb4500cad19aec81e841686ade1f31f67f)
1596fdf75SMatt Arsenault //===- ReduceOpcodes.cpp - Specialized Delta Pass -------------------------===//
2596fdf75SMatt Arsenault //
3596fdf75SMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4596fdf75SMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
5596fdf75SMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6596fdf75SMatt Arsenault //
7596fdf75SMatt Arsenault //===----------------------------------------------------------------------===//
8596fdf75SMatt Arsenault 
9596fdf75SMatt Arsenault #include "ReduceMemoryOperations.h"
10596fdf75SMatt Arsenault #include "Delta.h"
11596fdf75SMatt Arsenault #include "llvm/IR/InstIterator.h"
12596fdf75SMatt Arsenault #include "llvm/IR/Instructions.h"
13596fdf75SMatt Arsenault #include "llvm/IR/IntrinsicInst.h"
14596fdf75SMatt Arsenault 
15*333ffafbSMatt Arsenault using namespace llvm;
16*333ffafbSMatt Arsenault 
removeVolatileInFunction(Oracle & O,Function & F)17596fdf75SMatt Arsenault static void removeVolatileInFunction(Oracle &O, Function &F) {
18596fdf75SMatt Arsenault   LLVMContext &Ctx = F.getContext();
19596fdf75SMatt Arsenault   for (Instruction &I : instructions(F)) {
20596fdf75SMatt Arsenault     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
21596fdf75SMatt Arsenault       if (LI->isVolatile() && !O.shouldKeep())
22596fdf75SMatt Arsenault         LI->setVolatile(false);
23596fdf75SMatt Arsenault     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
24596fdf75SMatt Arsenault       if (SI->isVolatile() && !O.shouldKeep())
25596fdf75SMatt Arsenault         SI->setVolatile(false);
26596fdf75SMatt Arsenault     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
27596fdf75SMatt Arsenault       if (RMW->isVolatile() && !O.shouldKeep())
28596fdf75SMatt Arsenault         RMW->setVolatile(false);
29596fdf75SMatt Arsenault     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
30596fdf75SMatt Arsenault       if (CmpXChg->isVolatile() && !O.shouldKeep())
31596fdf75SMatt Arsenault         CmpXChg->setVolatile(false);
32596fdf75SMatt Arsenault     } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) {
33596fdf75SMatt Arsenault       if (MemIntrin->isVolatile() && !O.shouldKeep())
34596fdf75SMatt Arsenault         MemIntrin->setVolatile(ConstantInt::getFalse(Ctx));
35596fdf75SMatt Arsenault     }
36596fdf75SMatt Arsenault   }
37596fdf75SMatt Arsenault }
38596fdf75SMatt Arsenault 
removeVolatileInModule(Oracle & O,ReducerWorkItem & WorkItem)3923cc36e4SMatt Arsenault static void removeVolatileInModule(Oracle &O, ReducerWorkItem &WorkItem) {
4023cc36e4SMatt Arsenault   for (Function &F : WorkItem.getModule())
41596fdf75SMatt Arsenault     removeVolatileInFunction(O, F);
42596fdf75SMatt Arsenault }
43596fdf75SMatt Arsenault 
reduceVolatileInstructionsDeltaPass(TestRunner & Test)44596fdf75SMatt Arsenault void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) {
45596fdf75SMatt Arsenault   runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions");
46596fdf75SMatt Arsenault }
47b1e17199SMatt Arsenault 
reduceAtomicSyncScopesInFunction(Oracle & O,Function & F)48b1e17199SMatt Arsenault static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) {
49b1e17199SMatt Arsenault   for (Instruction &I : instructions(F)) {
50b1e17199SMatt Arsenault     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
51b1e17199SMatt Arsenault       if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
52b1e17199SMatt Arsenault         LI->setSyncScopeID(SyncScope::System);
53b1e17199SMatt Arsenault     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
54b1e17199SMatt Arsenault       if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
55b1e17199SMatt Arsenault         SI->setSyncScopeID(SyncScope::System);
56b1e17199SMatt Arsenault     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
57b1e17199SMatt Arsenault       if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
58b1e17199SMatt Arsenault         RMW->setSyncScopeID(SyncScope::System);
59b1e17199SMatt Arsenault     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
60b1e17199SMatt Arsenault       if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
61b1e17199SMatt Arsenault         CmpXChg->setSyncScopeID(SyncScope::System);
62b1e17199SMatt Arsenault     } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) {
63b1e17199SMatt Arsenault       if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
64b1e17199SMatt Arsenault         Fence->setSyncScopeID(SyncScope::System);
65b1e17199SMatt Arsenault     }
66b1e17199SMatt Arsenault   }
67b1e17199SMatt Arsenault }
68b1e17199SMatt Arsenault 
reduceAtomicSyncScopesInModule(Oracle & O,ReducerWorkItem & WorkItem)6923cc36e4SMatt Arsenault static void reduceAtomicSyncScopesInModule(Oracle &O,
7023cc36e4SMatt Arsenault                                            ReducerWorkItem &WorkItem) {
7123cc36e4SMatt Arsenault   for (Function &F : WorkItem.getModule())
72b1e17199SMatt Arsenault     reduceAtomicSyncScopesInFunction(O, F);
73b1e17199SMatt Arsenault }
74b1e17199SMatt Arsenault 
reduceAtomicSyncScopesDeltaPass(TestRunner & Test)75b1e17199SMatt Arsenault void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) {
76b1e17199SMatt Arsenault   runDeltaPass(Test, reduceAtomicSyncScopesInModule,
77b1e17199SMatt Arsenault                "Reducing Atomic Sync Scopes");
78b1e17199SMatt Arsenault }
7983da1a6aSMatt Arsenault 
8083da1a6aSMatt Arsenault // TODO: Might be helpful to incrementally relax orders
reduceAtomicOrderingInFunction(Oracle & O,Function & F)8183da1a6aSMatt Arsenault static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) {
8283da1a6aSMatt Arsenault   for (Instruction &I : instructions(F)) {
8383da1a6aSMatt Arsenault     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
8483da1a6aSMatt Arsenault       if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
8583da1a6aSMatt Arsenault         LI->setAtomic(AtomicOrdering::NotAtomic);
8683da1a6aSMatt Arsenault     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
8783da1a6aSMatt Arsenault       if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
8883da1a6aSMatt Arsenault         SI->setAtomic(AtomicOrdering::NotAtomic);
8983da1a6aSMatt Arsenault     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
9083da1a6aSMatt Arsenault       if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep())
9183da1a6aSMatt Arsenault         RMW->setOrdering(AtomicOrdering::Monotonic);
9283da1a6aSMatt Arsenault     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
9383da1a6aSMatt Arsenault       if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic &&
9483da1a6aSMatt Arsenault           !O.shouldKeep())
9583da1a6aSMatt Arsenault         CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic);
9683da1a6aSMatt Arsenault       if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic &&
9783da1a6aSMatt Arsenault           !O.shouldKeep())
9883da1a6aSMatt Arsenault         CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic);
9983da1a6aSMatt Arsenault     }
10083da1a6aSMatt Arsenault   }
10183da1a6aSMatt Arsenault }
10283da1a6aSMatt Arsenault 
reduceAtomicOrderingInModule(Oracle & O,ReducerWorkItem & WorkItem)10323cc36e4SMatt Arsenault static void reduceAtomicOrderingInModule(Oracle &O, ReducerWorkItem &WorkItem) {
10423cc36e4SMatt Arsenault   for (Function &F : WorkItem.getModule())
10583da1a6aSMatt Arsenault     reduceAtomicOrderingInFunction(O, F);
10683da1a6aSMatt Arsenault }
10783da1a6aSMatt Arsenault 
reduceAtomicOrderingDeltaPass(TestRunner & Test)10883da1a6aSMatt Arsenault void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) {
109756ee72aSMatt Arsenault   runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Ordering");
11083da1a6aSMatt Arsenault }
111