1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s 2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} 3 4; CHECK-DAG: OpName [[ADD:%.*]] "test_add" 5; CHECK-DAG: OpName [[SUB:%.*]] "test_sub" 6; CHECK-DAG: OpName [[MIN:%.*]] "test_min" 7; CHECK-DAG: OpName [[MAX:%.*]] "test_max" 8; CHECK-DAG: OpName [[UMIN:%.*]] "test_umin" 9; CHECK-DAG: OpName [[UMAX:%.*]] "test_umax" 10; CHECK-DAG: OpName [[AND:%.*]] "test_and" 11; CHECK-DAG: OpName [[OR:%.*]] "test_or" 12; CHECK-DAG: OpName [[XOR:%.*]] "test_xor" 13 14; CHECK-DAG: [[I32Ty:%.*]] = OpTypeInt 32 0 15; CHECK-DAG: [[PtrI32Ty:%.*]] = OpTypePointer Function [[I32Ty]] 16;; AllSvmDevices scope is encoded with constant 0 17; CHECK-DAG: [[SCOPE:%.*]] = OpConstantNull [[I32Ty]] 18;; "acq_rel" maps to the constant 8 19; CHECK-DAG: [[ACQREL:%.*]] = OpConstant [[I32Ty]] 8 20 21; CHECK: [[ADD]] = OpFunction [[I32Ty]] 22; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 23; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 24; CHECK-NEXT: OpLabel 25; CHECK-NEXT: [[R:%.*]] = OpAtomicIAdd [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 26; CHECK-NEXT: OpReturnValue [[R]] 27; CHECK-NEXT: OpFunctionEnd 28define i32 @test_add(i32* %ptr, i32 %val) { 29 %r = atomicrmw add i32* %ptr, i32 %val acq_rel 30 ret i32 %r 31} 32 33; CHECK: [[SUB]] = OpFunction [[I32Ty]] 34; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 35; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 36; CHECK-NEXT: OpLabel 37; CHECK-NEXT: [[R:%.*]] = OpAtomicISub [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 38; CHECK-NEXT: OpReturnValue [[R]] 39; CHECK-NEXT: OpFunctionEnd 40define i32 @test_sub(i32* %ptr, i32 %val) { 41 %r = atomicrmw sub i32* %ptr, i32 %val acq_rel 42 ret i32 %r 43} 44 45; CHECK: [[MIN]] = OpFunction [[I32Ty]] 46; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 47; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 48; CHECK-NEXT: OpLabel 49; CHECK-NEXT: [[R:%.*]] = OpAtomicSMin [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 50; CHECK-NEXT: OpReturnValue [[R]] 51; CHECK-NEXT: OpFunctionEnd 52define i32 @test_min(i32* %ptr, i32 %val) { 53 %r = atomicrmw min i32* %ptr, i32 %val acq_rel 54 ret i32 %r 55} 56 57; CHECK: [[MAX]] = OpFunction [[I32Ty]] 58; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 59; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 60; CHECK-NEXT: OpLabel 61; CHECK-NEXT: [[R:%.*]] = OpAtomicSMax [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 62; CHECK-NEXT: OpReturnValue [[R]] 63; CHECK-NEXT: OpFunctionEnd 64define i32 @test_max(i32* %ptr, i32 %val) { 65 %r = atomicrmw max i32* %ptr, i32 %val acq_rel 66 ret i32 %r 67} 68 69; CHECK: [[UMIN]] = OpFunction [[I32Ty]] 70; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 71; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 72; CHECK-NEXT: OpLabel 73; CHECK-NEXT: [[R:%.*]] = OpAtomicUMin [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 74; CHECK-NEXT: OpReturnValue [[R]] 75; CHECK-NEXT: OpFunctionEnd 76define i32 @test_umin(i32* %ptr, i32 %val) { 77 %r = atomicrmw umin i32* %ptr, i32 %val acq_rel 78 ret i32 %r 79} 80 81; CHECK: [[UMAX]] = OpFunction [[I32Ty]] 82; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 83; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 84; CHECK-NEXT: OpLabel 85; CHECK-NEXT: [[R:%.*]] = OpAtomicUMax [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 86; CHECK-NEXT: OpReturnValue [[R]] 87; CHECK-NEXT: OpFunctionEnd 88define i32 @test_umax(i32* %ptr, i32 %val) { 89 %r = atomicrmw umax i32* %ptr, i32 %val acq_rel 90 ret i32 %r 91} 92 93; CHECK: [[AND]] = OpFunction [[I32Ty]] 94; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 95; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 96; CHECK-NEXT: OpLabel 97; CHECK-NEXT: [[R:%.*]] = OpAtomicAnd [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 98; CHECK-NEXT: OpReturnValue [[R]] 99; CHECK-NEXT: OpFunctionEnd 100define i32 @test_and(i32* %ptr, i32 %val) { 101 %r = atomicrmw and i32* %ptr, i32 %val acq_rel 102 ret i32 %r 103} 104 105; CHECK: [[OR]] = OpFunction [[I32Ty]] 106; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 107; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 108; CHECK-NEXT: OpLabel 109; CHECK-NEXT: [[R:%.*]] = OpAtomicOr [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 110; CHECK-NEXT: OpReturnValue [[R]] 111; CHECK-NEXT: OpFunctionEnd 112define i32 @test_or(i32* %ptr, i32 %val) { 113 %r = atomicrmw or i32* %ptr, i32 %val acq_rel 114 ret i32 %r 115} 116 117; CHECK: [[XOR]] = OpFunction [[I32Ty]] 118; CHECK-NEXT: [[A:%.*]] = OpFunctionParameter [[PtrI32Ty]] 119; CHECK-NEXT: [[B:%.*]] = OpFunctionParameter [[I32Ty]] 120; CHECK-NEXT: OpLabel 121; CHECK-NEXT: [[R:%.*]] = OpAtomicXor [[I32Ty]] [[A]] [[SCOPE]] [[ACQREL]] [[B]] 122; CHECK-NEXT: OpReturnValue [[R]] 123; CHECK-NEXT: OpFunctionEnd 124define i32 @test_xor(i32* %ptr, i32 %val) { 125 %r = atomicrmw xor i32* %ptr, i32 %val acq_rel 126 ret i32 %r 127} 128