| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| ; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=volatile --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: @load_volatile_keep( | ||
| ; INTERESTING: load volatile | ||
| ; RESULT: %op = load volatile i32, | ||
| define i32 @load_volatile_keep(ptr %ptr) { | ||
| %op = load volatile i32, ptr %ptr | ||
| ret i32 %op | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @load_volatile_drop( | ||
| ; INTERESTING: load | ||
| ; RESULT: %op = load i32, | ||
| define i32 @load_volatile_drop(ptr %ptr) { | ||
| %op = load volatile i32, ptr %ptr | ||
| ret i32 %op | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @store_volatile_keep( | ||
| ; INTERESTING: store volatile | ||
| ; RESULT: store volatile i32 0, | ||
| define void @store_volatile_keep(ptr %ptr) { | ||
| store volatile i32 0, ptr %ptr | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @store_volatile_drop( | ||
| ; INTERESTING: store | ||
| ; RESULT: store i32 0, | ||
| define void @store_volatile_drop(ptr %ptr) { | ||
| store volatile i32 0, ptr %ptr | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @atomicrmw_volatile_keep( | ||
| ; INTERESTING: atomicrmw volatile | ||
| ; RESULT: atomicrmw volatile add ptr %ptr | ||
| define i32 @atomicrmw_volatile_keep(ptr %ptr) { | ||
| %val = atomicrmw volatile add ptr %ptr, i32 3 seq_cst | ||
| ret i32 %val | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @atomicrmw_volatile_drop( | ||
| ; INTERESTING: atomicrmw | ||
| ; RESULT: atomicrmw add ptr %ptr | ||
| define i32 @atomicrmw_volatile_drop(ptr %ptr) { | ||
| %val = atomicrmw volatile add ptr %ptr, i32 3 seq_cst | ||
| ret i32 %val | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @cmpxchg_volatile_keep( | ||
| ; INTERESTING: cmpxchg volatile | ||
| ; RESULT: cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst | ||
| define { i32, i1 } @cmpxchg_volatile_keep(ptr %ptr, i32 %old, i32 %in) { | ||
| %val = cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst | ||
| ret { i32, i1 } %val | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @cmpxchg_volatile_drop( | ||
| ; INTERESTING: cmpxchg | ||
| ; RESULT: cmpxchg ptr %ptr, i32 %old, i32 %in seq_cst seq_cst | ||
| define { i32, i1 } @cmpxchg_volatile_drop(ptr %ptr, i32 %old, i32 %in) { | ||
| %val = cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst | ||
| ret { i32, i1 } %val | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memcpy_volatile_keep( | ||
| ; INTERESTING: i1 true | ||
| ; RESULT: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true) | ||
| define void @memcpy_volatile_keep(ptr %dst, ptr %src, i64 %size) { | ||
| call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memcpy_volatile_drop( | ||
| ; INTERESTING: llvm.memcpy | ||
| ; RESULT: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 false) | ||
| define void @memcpy_volatile_drop(ptr %dst, ptr %src, i64 %size) { | ||
| call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memcpy_inline_volatile_keep( | ||
| ; INTERESTING: i1 true | ||
| ; RESULT: call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true) | ||
| define void @memcpy_inline_volatile_keep(ptr %dst, ptr %src) { | ||
| call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memcpy_inline_volatile_drop( | ||
| ; INTERESTING: llvm.memcpy | ||
| ; RESULT: call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 false) | ||
| define void @memcpy_inline_volatile_drop(ptr %dst, ptr %src) { | ||
| call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memmove_volatile_keep( | ||
| ; INTERESTING: i1 true | ||
| ; RESULT: call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true) | ||
| define void @memmove_volatile_keep(ptr %dst, ptr %src) { | ||
| call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memmove_volatile_drop( | ||
| ; INTERESTING: llvm.memmove | ||
| ; RESULT: call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 false) | ||
| define void @memmove_volatile_drop(ptr %dst, ptr %src, i64 %size) { | ||
| call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memset_volatile_keep( | ||
| ; INTERESTING: i1 true | ||
| ; RESULT: call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true) | ||
| define void @memset_volatile_keep(ptr %ptr, i8 %val, i64 %size) { | ||
| call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: @memset_volatile_drop( | ||
| ; INTERESTING: llvm.memset | ||
| ; RESULT: call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 false) | ||
| define void @memset_volatile_drop(ptr %ptr, i8 %val, i64 %size) { | ||
| call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true) | ||
| ret void | ||
| } | ||
|
|
||
| declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) | ||
| declare void @llvm.memmove.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) | ||
| declare void @llvm.memcpy.inline.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64 immarg, i1 immarg) | ||
| declare void @llvm.memset.p0.i64(ptr noalias nocapture readonly, i8, i64, i1 immarg) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<OverflowingBinaryOperator>(&I)) { | ||
| if (OBO->hasNoSignedWrap() && !O.shouldKeep()) | ||
| I.setHasNoSignedWrap(false); | ||
| if (OBO->hasNoUnsignedWrap() && !O.shouldKeep()) | ||
| I.setHasNoUnsignedWrap(false); | ||
| } else if (auto *PE = dyn_cast<PossiblyExactOperator>(&I)) { | ||
| if (PE->isExact() && !O.shouldKeep()) | ||
| I.setIsExact(false); | ||
| } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) { | ||
| if (GEP->isInBounds() && !O.shouldKeep()) | ||
| GEP->setIsInBounds(false); | ||
| } else if (auto *FPOp = dyn_cast<FPMathOperator>(&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"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| //===- ReduceOpcodes.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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "ReduceMemoryOperations.h" | ||
| #include "Delta.h" | ||
| #include "llvm/IR/InstIterator.h" | ||
| #include "llvm/IR/Instructions.h" | ||
| #include "llvm/IR/IntrinsicInst.h" | ||
|
|
||
| static void removeVolatileInFunction(Oracle &O, Function &F) { | ||
| LLVMContext &Ctx = F.getContext(); | ||
| for (Instruction &I : instructions(F)) { | ||
| if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { | ||
| if (LI->isVolatile() && !O.shouldKeep()) | ||
| LI->setVolatile(false); | ||
| } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { | ||
| if (SI->isVolatile() && !O.shouldKeep()) | ||
| SI->setVolatile(false); | ||
| } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { | ||
| if (RMW->isVolatile() && !O.shouldKeep()) | ||
| RMW->setVolatile(false); | ||
| } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { | ||
| if (CmpXChg->isVolatile() && !O.shouldKeep()) | ||
| CmpXChg->setVolatile(false); | ||
| } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) { | ||
| if (MemIntrin->isVolatile() && !O.shouldKeep()) | ||
| MemIntrin->setVolatile(ConstantInt::getFalse(Ctx)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void removeVolatileInModule(Oracle &O, Module &Mod) { | ||
| for (Function &F : Mod) | ||
| removeVolatileInFunction(O, F); | ||
| } | ||
|
|
||
| void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) { | ||
| runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions"); | ||
| } | ||
|
|
||
| static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) { | ||
| for (Instruction &I : instructions(F)) { | ||
| if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { | ||
| if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) | ||
| LI->setSyncScopeID(SyncScope::System); | ||
| } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { | ||
| if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) | ||
| SI->setSyncScopeID(SyncScope::System); | ||
| } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { | ||
| if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) | ||
| RMW->setSyncScopeID(SyncScope::System); | ||
| } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { | ||
| if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) | ||
| CmpXChg->setSyncScopeID(SyncScope::System); | ||
| } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) { | ||
| if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep()) | ||
| Fence->setSyncScopeID(SyncScope::System); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void reduceAtomicSyncScopesInModule(Oracle &O, Module &Mod) { | ||
| for (Function &F : Mod) | ||
| reduceAtomicSyncScopesInFunction(O, F); | ||
| } | ||
|
|
||
| void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) { | ||
| runDeltaPass(Test, reduceAtomicSyncScopesInModule, | ||
| "Reducing Atomic Sync Scopes"); | ||
| } | ||
|
|
||
| // TODO: Might be helpful to incrementally relax orders | ||
| static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) { | ||
| for (Instruction &I : instructions(F)) { | ||
| if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { | ||
| if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep()) | ||
| LI->setAtomic(AtomicOrdering::NotAtomic); | ||
| } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { | ||
| if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep()) | ||
| SI->setAtomic(AtomicOrdering::NotAtomic); | ||
| } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) { | ||
| if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep()) | ||
| RMW->setOrdering(AtomicOrdering::Monotonic); | ||
| } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) { | ||
| if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic && | ||
| !O.shouldKeep()) | ||
| CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic); | ||
| if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic && | ||
| !O.shouldKeep()) | ||
| CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void reduceAtomicOrderingInModule(Oracle &O, Module &Mod) { | ||
| for (Function &F : Mod) | ||
| reduceAtomicOrderingInFunction(O, F); | ||
| } | ||
|
|
||
| void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) { | ||
| runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Odering"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===- ReduceMemoryOperations.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_REDUCEMEMORYOPERATIONS_H | ||
| #define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEMEMORYOPERATIONS_H | ||
|
|
||
| #include "TestRunner.h" | ||
|
|
||
| namespace llvm { | ||
| void reduceVolatileInstructionsDeltaPass(TestRunner &Test); | ||
| void reduceAtomicSyncScopesDeltaPass(TestRunner &Test); | ||
| void reduceAtomicOrderingDeltaPass(TestRunner &Test); | ||
| } // namespace llvm | ||
|
|
||
| #endif |