Skip to content

Commit f6a14a0

Browse files
authored
[IR] Check identical alignment for atomic instructions (#155349)
I noticed that `hasSameSpecialState()` checks alignment for `load`/`store` instructions, but not for `cmpxchg` or `atomicrmw`, which I assume is a bug. It looks like alignment for these instructions were added in 74c7237.
1 parent fc8f54d commit f6a14a0

File tree

3 files changed

+171
-1
lines changed

3 files changed

+171
-1
lines changed

llvm/lib/IR/Instruction.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
865865
bool Instruction::hasSameSpecialState(const Instruction *I2,
866866
bool IgnoreAlignment,
867867
bool IntersectAttrs) const {
868-
auto I1 = this;
868+
const auto *I1 = this;
869869
assert(I1->getOpcode() == I2->getOpcode() &&
870870
"Can not compare special state of different instructions");
871871

@@ -918,6 +918,8 @@ bool Instruction::hasSameSpecialState(const Instruction *I2,
918918
FI->getSyncScopeID() == cast<FenceInst>(I2)->getSyncScopeID();
919919
if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(I1))
920920
return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I2)->isVolatile() &&
921+
(CXI->getAlign() == cast<AtomicCmpXchgInst>(I2)->getAlign() ||
922+
IgnoreAlignment) &&
921923
CXI->isWeak() == cast<AtomicCmpXchgInst>(I2)->isWeak() &&
922924
CXI->getSuccessOrdering() ==
923925
cast<AtomicCmpXchgInst>(I2)->getSuccessOrdering() &&
@@ -928,6 +930,8 @@ bool Instruction::hasSameSpecialState(const Instruction *I2,
928930
if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I1))
929931
return RMWI->getOperation() == cast<AtomicRMWInst>(I2)->getOperation() &&
930932
RMWI->isVolatile() == cast<AtomicRMWInst>(I2)->isVolatile() &&
933+
(RMWI->getAlign() == cast<AtomicRMWInst>(I2)->getAlign() ||
934+
IgnoreAlignment) &&
931935
RMWI->getOrdering() == cast<AtomicRMWInst>(I2)->getOrdering() &&
932936
RMWI->getSyncScopeID() == cast<AtomicRMWInst>(I2)->getSyncScopeID();
933937
if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I1))
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
2+
; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
3+
4+
declare void @foo();
5+
6+
define void @atomicrmw_base(ptr %p) {
7+
entry:
8+
%1 = atomicrmw add ptr %p, i32 1 acquire, align 8
9+
call void @foo()
10+
ret void
11+
}
12+
13+
define void @atomicrmw_copy(ptr %p) {
14+
entry:
15+
%1 = atomicrmw add ptr %p, i32 1 acquire, align 8
16+
call void @foo()
17+
ret void
18+
}
19+
20+
define void @atomicrmw_wrong_type(ptr %p) {
21+
entry:
22+
%1 = atomicrmw add ptr %p, i64 1 acquire, align 8
23+
call void @foo()
24+
ret void
25+
}
26+
27+
define void @atomicrmw_wrong_align(ptr %p) {
28+
entry:
29+
%1 = atomicrmw add ptr %p, i32 1 acquire, align 4
30+
call void @foo()
31+
ret void
32+
}
33+
34+
define void @atomicrmw_wrong_volatile(ptr %p) {
35+
entry:
36+
%1 = atomicrmw volatile add ptr %p, i32 1 acquire, align 8
37+
call void @foo()
38+
ret void
39+
}
40+
41+
define void @cmpxchg_base(ptr %p) {
42+
entry:
43+
%1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 8
44+
call void @foo()
45+
ret void
46+
}
47+
48+
define void @cmpxchg_copy(ptr %p) {
49+
entry:
50+
%1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 8
51+
call void @foo()
52+
ret void
53+
}
54+
55+
define void @cmpxchg_wrong_type(ptr %p) {
56+
entry:
57+
%1 = cmpxchg ptr %p, i64 0, i64 1 monotonic monotonic, align 8
58+
call void @foo()
59+
ret void
60+
}
61+
62+
define void @cmpxchg_wrong_align(ptr %p) {
63+
entry:
64+
%1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 4
65+
call void @foo()
66+
ret void
67+
}
68+
69+
define void @cmpxchg_wrong_volatile(ptr %p) {
70+
entry:
71+
%1 = cmpxchg volatile ptr %p, i32 0, i32 1 monotonic monotonic, align 8
72+
call void @foo()
73+
ret void
74+
}
75+
76+
77+
; CHECK-LABEL: @atomicrmw_base(
78+
; CHECK-NEXT: entry:
79+
; CHECK-NEXT: call void @outlined_ir_func_1(ptr [[P:%.*]])
80+
; CHECK-NEXT: ret void
81+
;
82+
;
83+
; CHECK-LABEL: @atomicrmw_copy(
84+
; CHECK-NEXT: entry:
85+
; CHECK-NEXT: call void @outlined_ir_func_1(ptr [[P:%.*]])
86+
; CHECK-NEXT: ret void
87+
;
88+
;
89+
; CHECK-LABEL: @atomicrmw_wrong_type(
90+
; CHECK-NEXT: entry:
91+
; CHECK-NEXT: [[TMP0:%.*]] = atomicrmw add ptr [[P:%.*]], i64 1 acquire, align 8
92+
; CHECK-NEXT: call void @foo()
93+
; CHECK-NEXT: ret void
94+
;
95+
;
96+
; CHECK-LABEL: @atomicrmw_wrong_align(
97+
; CHECK-NEXT: entry:
98+
; CHECK-NEXT: [[TMP0:%.*]] = atomicrmw add ptr [[P:%.*]], i32 1 acquire, align 4
99+
; CHECK-NEXT: call void @foo()
100+
; CHECK-NEXT: ret void
101+
;
102+
;
103+
; CHECK-LABEL: @atomicrmw_wrong_volatile(
104+
; CHECK-NEXT: entry:
105+
; CHECK-NEXT: [[TMP0:%.*]] = atomicrmw volatile add ptr [[P:%.*]], i32 1 acquire, align 8
106+
; CHECK-NEXT: call void @foo()
107+
; CHECK-NEXT: ret void
108+
;
109+
;
110+
; CHECK-LABEL: @cmpxchg_base(
111+
; CHECK-NEXT: entry:
112+
; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[P:%.*]])
113+
; CHECK-NEXT: ret void
114+
;
115+
;
116+
; CHECK-LABEL: @cmpxchg_copy(
117+
; CHECK-NEXT: entry:
118+
; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[P:%.*]])
119+
; CHECK-NEXT: ret void
120+
;
121+
;
122+
; CHECK-LABEL: @cmpxchg_wrong_type(
123+
; CHECK-NEXT: entry:
124+
; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg ptr [[P:%.*]], i64 0, i64 1 monotonic monotonic, align 8
125+
; CHECK-NEXT: call void @foo()
126+
; CHECK-NEXT: ret void
127+
;
128+
;
129+
; CHECK-LABEL: @cmpxchg_wrong_align(
130+
; CHECK-NEXT: entry:
131+
; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg ptr [[P:%.*]], i32 0, i32 1 monotonic monotonic, align 4
132+
; CHECK-NEXT: call void @foo()
133+
; CHECK-NEXT: ret void
134+
;
135+
;
136+
; CHECK-LABEL: @cmpxchg_wrong_volatile(
137+
; CHECK-NEXT: entry:
138+
; CHECK-NEXT: [[TMP0:%.*]] = cmpxchg volatile ptr [[P:%.*]], i32 0, i32 1 monotonic monotonic, align 8
139+
; CHECK-NEXT: call void @foo()
140+
; CHECK-NEXT: ret void
141+
;
142+
;
143+
; CHECK-LABEL: @outlined_ir_func_0(
144+
; CHECK-NEXT: newFuncRoot:
145+
; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]]
146+
; CHECK: entry_to_outline:
147+
; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[TMP0:%.*]], i32 0, i32 1 monotonic monotonic, align 8
148+
; CHECK-NEXT: call void @foo()
149+
; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
150+
; CHECK: entry_after_outline.exitStub:
151+
; CHECK-NEXT: ret void
152+
;
153+
;
154+
; CHECK-LABEL: @outlined_ir_func_1(
155+
; CHECK-NEXT: newFuncRoot:
156+
; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]]
157+
; CHECK: entry_to_outline:
158+
; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[TMP0:%.*]], i32 1 acquire, align 8
159+
; CHECK-NEXT: call void @foo()
160+
; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
161+
; CHECK: entry_after_outline.exitStub:
162+
; CHECK-NEXT: ret void
163+
;

llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ void getSimilarities(
4949
SimilarityCandidates = Identifier.findSimilarity(M);
5050
}
5151

52+
// TODO: All these tests could probably become IR LIT tests like
53+
// IROutliner/outlining-special-state.ll
54+
5255
// Checks that different opcodes are mapped to different values
5356
TEST(IRInstructionMapper, OpcodeDifferentiation) {
5457
StringRef ModuleString = R"(

0 commit comments

Comments
 (0)