Skip to content

Commit 596fdf7

Browse files
committed
llvm-reduce: Add volatile reduction pass
Removing volatile may help optimization passes do more to the IR. However, this will increase scheduler freedom.
1 parent 27902ee commit 596fdf7

File tree

5 files changed

+200
-0
lines changed

5 files changed

+200
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
; 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
2+
; RUN: FileCheck -check-prefixes=RESULT,CHECK %s < %t
3+
4+
; CHECK-LABEL: @load_volatile_keep(
5+
; INTERESTING: load volatile
6+
; RESULT: %op = load volatile i32,
7+
define i32 @load_volatile_keep(ptr %ptr) {
8+
%op = load volatile i32, ptr %ptr
9+
ret i32 %op
10+
}
11+
12+
; CHECK-LABEL: @load_volatile_drop(
13+
; INTERESTING: load
14+
; RESULT: %op = load i32,
15+
define i32 @load_volatile_drop(ptr %ptr) {
16+
%op = load volatile i32, ptr %ptr
17+
ret i32 %op
18+
}
19+
20+
; CHECK-LABEL: @store_volatile_keep(
21+
; INTERESTING: store volatile
22+
; RESULT: store volatile i32 0,
23+
define void @store_volatile_keep(ptr %ptr) {
24+
store volatile i32 0, ptr %ptr
25+
ret void
26+
}
27+
28+
; CHECK-LABEL: @store_volatile_drop(
29+
; INTERESTING: store
30+
; RESULT: store i32 0,
31+
define void @store_volatile_drop(ptr %ptr) {
32+
store volatile i32 0, ptr %ptr
33+
ret void
34+
}
35+
36+
; CHECK-LABEL: @atomicrmw_volatile_keep(
37+
; INTERESTING: atomicrmw volatile
38+
; RESULT: atomicrmw volatile add ptr %ptr
39+
define i32 @atomicrmw_volatile_keep(ptr %ptr) {
40+
%val = atomicrmw volatile add ptr %ptr, i32 3 seq_cst
41+
ret i32 %val
42+
}
43+
44+
; CHECK-LABEL: @atomicrmw_volatile_drop(
45+
; INTERESTING: atomicrmw
46+
; RESULT: atomicrmw add ptr %ptr
47+
define i32 @atomicrmw_volatile_drop(ptr %ptr) {
48+
%val = atomicrmw volatile add ptr %ptr, i32 3 seq_cst
49+
ret i32 %val
50+
}
51+
52+
; CHECK-LABEL: @cmpxchg_volatile_keep(
53+
; INTERESTING: cmpxchg volatile
54+
; RESULT: cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst
55+
define { i32, i1 } @cmpxchg_volatile_keep(ptr %ptr, i32 %old, i32 %in) {
56+
%val = cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst
57+
ret { i32, i1 } %val
58+
}
59+
60+
; CHECK-LABEL: @cmpxchg_volatile_drop(
61+
; INTERESTING: cmpxchg
62+
; RESULT: cmpxchg ptr %ptr, i32 %old, i32 %in seq_cst seq_cst
63+
define { i32, i1 } @cmpxchg_volatile_drop(ptr %ptr, i32 %old, i32 %in) {
64+
%val = cmpxchg volatile ptr %ptr, i32 %old, i32 %in seq_cst seq_cst
65+
ret { i32, i1 } %val
66+
}
67+
68+
; CHECK-LABEL: @memcpy_volatile_keep(
69+
; INTERESTING: i1 true
70+
; RESULT: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true)
71+
define void @memcpy_volatile_keep(ptr %dst, ptr %src, i64 %size) {
72+
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true)
73+
ret void
74+
}
75+
76+
; CHECK-LABEL: @memcpy_volatile_drop(
77+
; INTERESTING: llvm.memcpy
78+
; RESULT: call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 false)
79+
define void @memcpy_volatile_drop(ptr %dst, ptr %src, i64 %size) {
80+
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true)
81+
ret void
82+
}
83+
84+
; CHECK-LABEL: @memcpy_inline_volatile_keep(
85+
; INTERESTING: i1 true
86+
; RESULT: call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true)
87+
define void @memcpy_inline_volatile_keep(ptr %dst, ptr %src) {
88+
call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true)
89+
ret void
90+
}
91+
92+
; CHECK-LABEL: @memcpy_inline_volatile_drop(
93+
; INTERESTING: llvm.memcpy
94+
; RESULT: call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 false)
95+
define void @memcpy_inline_volatile_drop(ptr %dst, ptr %src) {
96+
call void @llvm.memcpy.inline.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true)
97+
ret void
98+
}
99+
100+
; CHECK-LABEL: @memmove_volatile_keep(
101+
; INTERESTING: i1 true
102+
; RESULT: call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true)
103+
define void @memmove_volatile_keep(ptr %dst, ptr %src) {
104+
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 256, i1 true)
105+
ret void
106+
}
107+
108+
; CHECK-LABEL: @memmove_volatile_drop(
109+
; INTERESTING: llvm.memmove
110+
; RESULT: call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 false)
111+
define void @memmove_volatile_drop(ptr %dst, ptr %src, i64 %size) {
112+
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 true)
113+
ret void
114+
}
115+
116+
; CHECK-LABEL: @memset_volatile_keep(
117+
; INTERESTING: i1 true
118+
; RESULT: call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true)
119+
define void @memset_volatile_keep(ptr %ptr, i8 %val, i64 %size) {
120+
call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true)
121+
ret void
122+
}
123+
124+
; CHECK-LABEL: @memset_volatile_drop(
125+
; INTERESTING: llvm.memset
126+
; RESULT: call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 false)
127+
define void @memset_volatile_drop(ptr %ptr, i8 %val, i64 %size) {
128+
call void @llvm.memset.p0.i64(ptr %ptr, i8 %val, i64 %size, i1 true)
129+
ret void
130+
}
131+
132+
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
133+
declare void @llvm.memmove.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
134+
declare void @llvm.memcpy.inline.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64 immarg, i1 immarg)
135+
declare void @llvm.memset.p0.i64(ptr noalias nocapture readonly, i8, i64, i1 immarg)

llvm/tools/llvm-reduce/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_llvm_tool(llvm-reduce
3939
deltas/ReduceInstructionFlags.cpp
4040
deltas/ReduceMetadata.cpp
4141
deltas/ReduceModuleData.cpp
42+
deltas/ReduceMemoryOperations.cpp
4243
deltas/ReduceOperandBundles.cpp
4344
deltas/ReduceOpcodes.cpp
4445
deltas/ReduceSpecialGlobals.cpp

llvm/tools/llvm-reduce/DeltaManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "deltas/ReduceInstructionFlagsMIR.h"
3232
#include "deltas/ReduceInstructions.h"
3333
#include "deltas/ReduceInstructionsMIR.h"
34+
#include "deltas/ReduceMemoryOperations.h"
3435
#include "deltas/ReduceMetadata.h"
3536
#include "deltas/ReduceModuleData.h"
3637
#include "deltas/ReduceOpcodes.h"
@@ -94,6 +95,7 @@ static cl::list<std::string>
9495
DELTA_PASS("attributes", reduceAttributesDeltaPass) \
9596
DELTA_PASS("module-data", reduceModuleDataDeltaPass) \
9697
DELTA_PASS("opcodes", reduceOpcodesDeltaPass) \
98+
DELTA_PASS("volatile", reduceVolatileInstructionsDeltaPass) \
9799
DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass) \
98100
} while (false)
99101

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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, Module &Mod) {
38+
for (Function &F : Mod)
39+
removeVolatileInFunction(O, F);
40+
}
41+
42+
void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) {
43+
runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions");
44+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===- ReduceMemoryOperations.h - Specialized Delta Pass --------*- C++ -*-===//
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+
#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEMEMORYOPERATIONS_H
10+
#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEMEMORYOPERATIONS_H
11+
12+
#include "TestRunner.h"
13+
14+
namespace llvm {
15+
void reduceVolatileInstructionsDeltaPass(TestRunner &Test);
16+
} // namespace llvm
17+
18+
#endif

0 commit comments

Comments
 (0)