Skip to content

Commit

Permalink
Translate cmpxchg instruction in case it is followed by store inst (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
vmaksimo authored Dec 28, 2020
1 parent 0588075 commit 6ff0261
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
12 changes: 12 additions & 0 deletions llvm-spirv/lib/SPIRV/SPIRVRegularizeLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ bool SPIRVRegularizeLLVM::regularize() {
// OpIEqual instruction. The OpIEqual instruction returns true if the
// original value equals to the comparator which matches with
// semantics of cmpxchg.
// In case the original value was stored as is without extraction, we
// create a composite type manually from OpAtomicCompareExchange and
// OpIEqual instructions, and replace the original value usage in
// Store insruction with the new composite type.
for (User *U : Cmpxchg->users()) {
if (auto *Extract = dyn_cast<ExtractValueInst>(U)) {
if (Extract->getIndices()[0] == 0) {
Expand All @@ -381,6 +385,14 @@ bool SPIRVRegularizeLLVM::regularize() {
assert(Extract->user_empty());
Extract->dropAllReferences();
ToErase.push_back(Extract);
} else if (auto *Store = dyn_cast<StoreInst>(U)) {
auto *Cmp = new ICmpInst(Store, CmpInst::ICMP_EQ, Res, Comparator,
"cmpxchg.success");
auto *Agg = InsertValueInst::Create(
UndefValue::get(Cmpxchg->getType()), Res, 0, "agg0", Store);
auto *AggStruct =
InsertValueInst::Create(Agg, Cmp, 1, "agg1", Store);
Store->getValueOperand()->replaceAllUsesWith(AggStruct);
}
}
if (Cmpxchg->user_empty())
Expand Down
23 changes: 23 additions & 0 deletions llvm-spirv/test/AtomicCompareExchange.ll
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
; CHECK-SPIRV: Constant [[Int]] [[MemScope_Device:[0-9]+]] 1
; CHECK-SPIRV: Constant [[Int]] [[MemSemEqual_SeqCst:[0-9]+]] 16
; CHECK-SPIRV: Constant [[Int]] [[MemSemUnequal_Acquire:[0-9]+]] 2
; CHECK-SPIRV: Constant [[Int]] [[Constant_456:[0-9]+]] 456
; CHECK-SPIRV: Constant [[Int]] [[Constant_128:[0-9]+]] 128
; CHECK-SPIRV: TypeBool [[Bool:[0-9]+]]
; CHECK-SPIRV: TypeStruct [[Struct:[0-9]+]] [[Int]] [[Bool]]
; CHECK-SPIRV: Undef [[Struct]] [[UndefStruct:[0-9]+]]

; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Pointer:[0-9]+]]
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Value_ptr:[0-9]+]]
Expand Down Expand Up @@ -40,6 +45,24 @@ cmpxchg.continue: ; preds = %cmpxchg.store_expec
ret void
}

; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Ptr:[0-9]+]]
; CHECK-SPIRV: FunctionParameter {{[0-9]+}} [[Store_ptr:[0-9]+]]

; CHECK-SPIRV: AtomicCompareExchange [[Int]] [[Res_1:[0-9]+]] [[Ptr]] [[MemScope_Device]]
; CHECK-SPIRV-SAME: [[MemSemEqual_SeqCst]] [[MemSemUnequal_Acquire]] [[Constant_456]] [[Constant_128]]
; CHECK-SPIRV: IEqual {{[0-9]+}} [[Success_1:[0-9]+]] [[Res_1]] [[Constant_128]]
; CHECK-SPIRV: CompositeInsert [[Struct]] [[Composite:[0-9]+]] [[Res_1]] [[UndefStruct]] 0
; CHECK-SPIRV: CompositeInsert [[Struct]] [[Composite_1:[0-9]+]] [[Success_1]] [[Composite]] 1
; CHECK-SPIRV: Store [[Store_ptr]] [[Composite_1]]

; Function Attrs: nounwind
define dso_local spir_func void @test2(i32* %ptr, {i32, i1}* %store_ptr) local_unnamed_addr #0 {
entry:
%0 = cmpxchg i32* %ptr, i32 128, i32 456 seq_cst acquire
store { i32, i1 } %0, { i32, i1 }* %store_ptr, align 4
ret void
}

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" }
attributes #1 = { nounwind }

Expand Down

0 comments on commit 6ff0261

Please sign in to comment.