From 596fdf75d99f83473295e6a619ffac5afa23dd8e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 21 Oct 2022 14:03:51 -0700 Subject: [PATCH] llvm-reduce: Add volatile reduction pass Removing volatile may help optimization passes do more to the IR. However, this will increase scheduler freedom. --- llvm/test/tools/llvm-reduce/reduce-volatile.ll | 135 +++++++++++++++++++++ llvm/tools/llvm-reduce/CMakeLists.txt | 1 + llvm/tools/llvm-reduce/DeltaManager.cpp | 2 + .../llvm-reduce/deltas/ReduceMemoryOperations.cpp | 44 +++++++ .../llvm-reduce/deltas/ReduceMemoryOperations.h | 18 +++ 5 files changed, 200 insertions(+) create mode 100644 llvm/test/tools/llvm-reduce/reduce-volatile.ll create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp create mode 100644 llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.h diff --git a/llvm/test/tools/llvm-reduce/reduce-volatile.ll b/llvm/test/tools/llvm-reduce/reduce-volatile.ll new file mode 100644 index 0000000..2f09cbc --- /dev/null +++ b/llvm/test/tools/llvm-reduce/reduce-volatile.ll @@ -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) diff --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt index f539449..de99d9d 100644 --- a/llvm/tools/llvm-reduce/CMakeLists.txt +++ b/llvm/tools/llvm-reduce/CMakeLists.txt @@ -39,6 +39,7 @@ add_llvm_tool(llvm-reduce deltas/ReduceInstructionFlags.cpp deltas/ReduceMetadata.cpp deltas/ReduceModuleData.cpp + deltas/ReduceMemoryOperations.cpp deltas/ReduceOperandBundles.cpp deltas/ReduceOpcodes.cpp deltas/ReduceSpecialGlobals.cpp diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp index dc9a583..30b4bde 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -31,6 +31,7 @@ #include "deltas/ReduceInstructionFlagsMIR.h" #include "deltas/ReduceInstructions.h" #include "deltas/ReduceInstructionsMIR.h" +#include "deltas/ReduceMemoryOperations.h" #include "deltas/ReduceMetadata.h" #include "deltas/ReduceModuleData.h" #include "deltas/ReduceOpcodes.h" @@ -94,6 +95,7 @@ static cl::list DELTA_PASS("attributes", reduceAttributesDeltaPass) \ DELTA_PASS("module-data", reduceModuleDataDeltaPass) \ DELTA_PASS("opcodes", reduceOpcodesDeltaPass) \ + DELTA_PASS("volatile", reduceVolatileInstructionsDeltaPass) \ DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass) \ } while (false) diff --git a/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp b/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp new file mode 100644 index 0000000..e20561f --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp @@ -0,0 +1,44 @@ +//===- 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(&I)) { + if (LI->isVolatile() && !O.shouldKeep()) + LI->setVolatile(false); + } else if (StoreInst *SI = dyn_cast(&I)) { + if (SI->isVolatile() && !O.shouldKeep()) + SI->setVolatile(false); + } else if (AtomicRMWInst *RMW = dyn_cast(&I)) { + if (RMW->isVolatile() && !O.shouldKeep()) + RMW->setVolatile(false); + } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast(&I)) { + if (CmpXChg->isVolatile() && !O.shouldKeep()) + CmpXChg->setVolatile(false); + } else if (MemIntrinsic *MemIntrin = dyn_cast(&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"); +} diff --git a/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.h b/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.h new file mode 100644 index 0000000..fcb9ed3 --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.h @@ -0,0 +1,18 @@ +//===- 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); +} // namespace llvm + +#endif -- 2.7.4