Skip to content

Commit f57e6c9

Browse files
authored
Translate cmpxchg instruction in case it is followed by store inst (#865)
1 parent 2494cb0 commit f57e6c9

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/SPIRV/SPIRVRegularizeLLVM.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ bool SPIRVRegularizeLLVM::regularize() {
341341
// OpIEqual instruction. The OpIEqual instruction returns true if the
342342
// original value equals to the comparator which matches with
343343
// semantics of cmpxchg.
344+
// In case the original value was stored as is without extraction, we
345+
// create a composite type manually from OpAtomicCompareExchange and
346+
// OpIEqual instructions, and replace the original value usage in
347+
// Store insruction with the new composite type.
344348
for (User *U : Cmpxchg->users()) {
345349
if (auto *Extract = dyn_cast<ExtractValueInst>(U)) {
346350
if (Extract->getIndices()[0] == 0) {
@@ -355,6 +359,14 @@ bool SPIRVRegularizeLLVM::regularize() {
355359
assert(Extract->user_empty());
356360
Extract->dropAllReferences();
357361
ToErase.push_back(Extract);
362+
} else if (auto *Store = dyn_cast<StoreInst>(U)) {
363+
auto *Cmp = new ICmpInst(Store, CmpInst::ICMP_EQ, Res, Comparator,
364+
"cmpxchg.success");
365+
auto *Agg = InsertValueInst::Create(
366+
UndefValue::get(Cmpxchg->getType()), Res, 0, "agg0", Store);
367+
auto *AggStruct =
368+
InsertValueInst::Create(Agg, Cmp, 1, "agg1", Store);
369+
Store->getValueOperand()->replaceAllUsesWith(AggStruct);
358370
}
359371
}
360372
if (Cmpxchg->user_empty())

test/AtomicCompareExchange.ll

100644100755
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
; CHECK-SPIRV: Constant [[Int]] [[MemScope_Device:[0-9]+]] 1
88
; CHECK-SPIRV: Constant [[Int]] [[MemSemEqual_SeqCst:[0-9]+]] 16
99
; CHECK-SPIRV: Constant [[Int]] [[MemSemUnequal_Acquire:[0-9]+]] 2
10+
; CHECK-SPIRV: Constant [[Int]] [[Constant_456:[0-9]+]] 456
11+
; CHECK-SPIRV: Constant [[Int]] [[Constant_128:[0-9]+]] 128
12+
; CHECK-SPIRV: TypeBool [[Bool:[0-9]+]]
13+
; CHECK-SPIRV: TypeStruct [[Struct:[0-9]+]] [[Int]] [[Bool]]
14+
; CHECK-SPIRV: Undef [[Struct]] [[UndefStruct:[0-9]+]]
1015

1116
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Pointer:[0-9]+]]
1217
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Value_ptr:[0-9]+]]
@@ -40,6 +45,24 @@ cmpxchg.continue: ; preds = %cmpxchg.store_expec
4045
ret void
4146
}
4247

48+
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Ptr:[0-9]+]]
49+
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Store_ptr:[0-9]+]]
50+
51+
; CHECK-SPIRV: AtomicCompareExchange [[Int]] [[Res_1:[0-9]+]] [[Ptr]] [[MemScope_Device]]
52+
; CHECK-SPIRV-SAME: [[MemSemEqual_SeqCst]] [[MemSemUnequal_Acquire]] [[Constant_456]] [[Constant_128]]
53+
; CHECK-SPIRV: IEqual {{[0-9]+}} [[Success_1:[0-9]+]] [[Res_1]] [[Constant_128]]
54+
; CHECK-SPIRV: CompositeInsert [[Struct]] [[Composite:[0-9]+]] [[Res_1]] [[UndefStruct]] 0
55+
; CHECK-SPIRV: CompositeInsert [[Struct]] [[Composite_1:[0-9]+]] [[Success_1]] [[Composite]] 1
56+
; CHECK-SPIRV: Store [[Store_ptr]] [[Composite_1]]
57+
58+
; Function Attrs: nounwind
59+
define dso_local spir_func void @test2(i32* %ptr, {i32, i1}* %store_ptr) local_unnamed_addr #0 {
60+
entry:
61+
%0 = cmpxchg i32* %ptr, i32 128, i32 456 seq_cst acquire
62+
store { i32, i1 } %0, { i32, i1 }* %store_ptr, align 4
63+
ret void
64+
}
65+
4366
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
4467
attributes #1 = { nounwind }
4568

0 commit comments

Comments
 (0)