Skip to content

Commit 687d59e

Browse files
committed
Translate cmpxchg instruction in case it is followed by store inst
1 parent 0588075 commit 687d59e

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

llvm-spirv/lib/SPIRV/SPIRVRegularizeLLVM.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ bool SPIRVRegularizeLLVM::regularize() {
367367
// OpIEqual instruction. The OpIEqual instruction returns true if the
368368
// original value equals to the comparator which matches with
369369
// semantics of cmpxchg.
370+
// In case the original value was stored as is without extraction, we
371+
// create a composite type manually from OpAtomicCompareExchange and
372+
// OpIEqual instructions, and replace the original value usage in
373+
// Store insruction with the new composite type.
370374
for (User *U : Cmpxchg->users()) {
371375
if (auto *Extract = dyn_cast<ExtractValueInst>(U)) {
372376
if (Extract->getIndices()[0] == 0) {
@@ -381,6 +385,14 @@ bool SPIRVRegularizeLLVM::regularize() {
381385
assert(Extract->user_empty());
382386
Extract->dropAllReferences();
383387
ToErase.push_back(Extract);
388+
} else if (auto *Store = dyn_cast<StoreInst>(U)) {
389+
auto *Cmp = new ICmpInst(Store, CmpInst::ICMP_EQ, Res, Comparator,
390+
"cmpxchg.success");
391+
auto *Agg = InsertValueInst::Create(
392+
UndefValue::get(Cmpxchg->getType()), Res, 0, "agg0", Store);
393+
auto *AggStruct =
394+
InsertValueInst::Create(Agg, Cmp, 1, "agg1", Store);
395+
Store->getValueOperand()->replaceAllUsesWith(AggStruct);
384396
}
385397
}
386398
if (Cmpxchg->user_empty())

llvm-spirv/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)