236 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 -passes=atomic-expand %s | FileCheck -check-prefixes=GFX1200 %s3; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -passes=atomic-expand %s | FileCheck -check-prefixes=GFX1250 %s4 5define void @system_atomic_store_unordered_float(ptr addrspace(5) %addr, float %val) {6; GFX1200-LABEL: define void @system_atomic_store_unordered_float(7; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {8; GFX1200-NEXT: store float [[VAL]], ptr addrspace(5) [[ADDR]], align 49; GFX1200-NEXT: ret void10;11; GFX1250-LABEL: define void @system_atomic_store_unordered_float(12; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], float [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {13; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr14; GFX1250-NEXT: store atomic float [[VAL]], ptr [[SCRATCH_ASCAST]] unordered, align 415; GFX1250-NEXT: ret void16;17 store atomic float %val, ptr addrspace(5) %addr unordered, align 418 ret void19}20 21define void @system_atomic_store_unordered_i32(ptr addrspace(5) %addr, i32 %val) {22; GFX1200-LABEL: define void @system_atomic_store_unordered_i32(23; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {24; GFX1200-NEXT: store i32 [[VAL]], ptr addrspace(5) [[ADDR]], align 425; GFX1200-NEXT: ret void26;27; GFX1250-LABEL: define void @system_atomic_store_unordered_i32(28; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {29; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr30; GFX1250-NEXT: store atomic i32 [[VAL]], ptr [[SCRATCH_ASCAST]] unordered, align 431; GFX1250-NEXT: ret void32;33 store atomic i32 %val, ptr addrspace(5) %addr unordered, align 434 ret void35}36 37define void @system_atomic_store_release_i32(ptr addrspace(5) %addr, i32 %val) {38; GFX1200-LABEL: define void @system_atomic_store_release_i32(39; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {40; GFX1200-NEXT: store i32 [[VAL]], ptr addrspace(5) [[ADDR]], align 441; GFX1200-NEXT: ret void42;43; GFX1250-LABEL: define void @system_atomic_store_release_i32(44; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {45; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr46; GFX1250-NEXT: store atomic i32 [[VAL]], ptr [[SCRATCH_ASCAST]] release, align 447; GFX1250-NEXT: ret void48;49 store atomic i32 %val, ptr addrspace(5) %addr release, align 450 ret void51}52 53define void @workgroup_atomic_store_release_i32(ptr addrspace(5) %addr, i32 %val) {54; GFX1200-LABEL: define void @workgroup_atomic_store_release_i32(55; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {56; GFX1200-NEXT: store i32 [[VAL]], ptr addrspace(5) [[ADDR]], align 457; GFX1200-NEXT: ret void58;59; GFX1250-LABEL: define void @workgroup_atomic_store_release_i32(60; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {61; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr62; GFX1250-NEXT: store atomic i32 [[VAL]], ptr [[SCRATCH_ASCAST]] syncscope("workgroup") release, align 463; GFX1250-NEXT: ret void64;65 store atomic i32 %val, ptr addrspace(5) %addr syncscope("workgroup") release, align 466 ret void67}68 69define float @system_atomic_load_unordered_float(ptr addrspace(5) %addr) {70; GFX1200-LABEL: define float @system_atomic_load_unordered_float(71; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {72; GFX1200-NEXT: [[VAL:%.*]] = load float, ptr addrspace(5) [[ADDR]], align 4, !invariant.load [[META0:![0-9]+]], !nontemporal [[META1:![0-9]+]]73; GFX1200-NEXT: ret float [[VAL]]74;75; GFX1250-LABEL: define float @system_atomic_load_unordered_float(76; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {77; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr78; GFX1250-NEXT: [[VAL:%.*]] = load atomic float, ptr [[SCRATCH_ASCAST]] unordered, align 4, !invariant.load [[META0:![0-9]+]], !nontemporal [[META1:![0-9]+]]79; GFX1250-NEXT: ret float [[VAL]]80;81 %val = load atomic float, ptr addrspace(5) %addr unordered, align 4, !invariant.load !1, !nontemporal !082 ret float %val83}84 85define i32 @system_atomic_load_unordered_i32(ptr addrspace(5) %addr) {86; GFX1200-LABEL: define i32 @system_atomic_load_unordered_i32(87; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {88; GFX1200-NEXT: [[VAL:%.*]] = load i32, ptr addrspace(5) [[ADDR]], align 489; GFX1200-NEXT: ret i32 [[VAL]]90;91; GFX1250-LABEL: define i32 @system_atomic_load_unordered_i32(92; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {93; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr94; GFX1250-NEXT: [[VAL:%.*]] = load atomic i32, ptr [[SCRATCH_ASCAST]] unordered, align 495; GFX1250-NEXT: ret i32 [[VAL]]96;97 %val = load atomic i32, ptr addrspace(5) %addr unordered, align 498 ret i32 %val99}100 101define i32 @system_atomic_load_acquire_i32(ptr addrspace(5) %addr) {102; GFX1200-LABEL: define i32 @system_atomic_load_acquire_i32(103; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {104; GFX1200-NEXT: [[VAL:%.*]] = load i32, ptr addrspace(5) [[ADDR]], align 4105; GFX1200-NEXT: ret i32 [[VAL]]106;107; GFX1250-LABEL: define i32 @system_atomic_load_acquire_i32(108; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {109; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr110; GFX1250-NEXT: [[VAL:%.*]] = load atomic i32, ptr [[SCRATCH_ASCAST]] acquire, align 4111; GFX1250-NEXT: ret i32 [[VAL]]112;113 %val = load atomic i32, ptr addrspace(5) %addr acquire, align 4114 ret i32 %val115}116 117define i32 @workgroup_atomic_load_acquire_i32(ptr addrspace(5) %addr) {118; GFX1200-LABEL: define i32 @workgroup_atomic_load_acquire_i32(119; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {120; GFX1200-NEXT: [[VAL:%.*]] = load i32, ptr addrspace(5) [[ADDR]], align 4121; GFX1200-NEXT: ret i32 [[VAL]]122;123; GFX1250-LABEL: define i32 @workgroup_atomic_load_acquire_i32(124; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]]) #[[ATTR0]] {125; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr126; GFX1250-NEXT: [[VAL:%.*]] = load atomic i32, ptr [[SCRATCH_ASCAST]] syncscope("workgroup") acquire, align 4127; GFX1250-NEXT: ret i32 [[VAL]]128;129 %val = load atomic i32, ptr addrspace(5) %addr syncscope("workgroup") acquire, align 4130 ret i32 %val131}132 133define i32 @system_atomic_cmpxchg_acq_rel_acquire_i32(ptr addrspace(5) %addr, i32 %old, i32 %in) {134; GFX1200-LABEL: define i32 @system_atomic_cmpxchg_acq_rel_acquire_i32(135; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[OLD:%.*]], i32 [[IN:%.*]]) #[[ATTR0]] {136; GFX1200-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(5) [[ADDR]], align 4137; GFX1200-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[OLD]]138; GFX1200-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[IN]], i32 [[TMP1]]139; GFX1200-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[ADDR]], align 4140; GFX1200-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } poison, i32 [[TMP1]], 0141; GFX1200-NEXT: [[TMP5:%.*]] = insertvalue { i32, i1 } [[TMP4]], i1 [[TMP2]], 1142; GFX1200-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0143; GFX1200-NEXT: ret i32 [[RES]]144;145; GFX1250-LABEL: define i32 @system_atomic_cmpxchg_acq_rel_acquire_i32(146; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[OLD:%.*]], i32 [[IN:%.*]]) #[[ATTR0]] {147; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr148; GFX1250-NEXT: [[VAL:%.*]] = cmpxchg volatile ptr [[SCRATCH_ASCAST]], i32 [[OLD]], i32 [[IN]] acq_rel acquire, align 4, !nontemporal [[META1]]149; GFX1250-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[VAL]], 0150; GFX1250-NEXT: ret i32 [[RES]]151;152 %val = cmpxchg volatile ptr addrspace(5) %addr, i32 %old, i32 %in acq_rel acquire, !nontemporal !0153 %res = extractvalue { i32, i1 } %val, 0154 ret i32 %res155}156 157define i32 @system_atomicrmw_xchg_acq_rel_i32(ptr addrspace(5) %addr, i32 %in) {158; GFX1200-LABEL: define i32 @system_atomicrmw_xchg_acq_rel_i32(159; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[IN:%.*]]) #[[ATTR0]] {160; GFX1200-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(5) [[ADDR]], align 4161; GFX1200-NEXT: store i32 [[IN]], ptr addrspace(5) [[ADDR]], align 4162; GFX1200-NEXT: ret i32 [[TMP1]]163;164; GFX1250-LABEL: define i32 @system_atomicrmw_xchg_acq_rel_i32(165; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i32 [[IN:%.*]]) #[[ATTR0]] {166; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr167; GFX1250-NEXT: [[VAL:%.*]] = atomicrmw volatile xchg ptr [[SCRATCH_ASCAST]], i32 [[IN]] acq_rel, align 4168; GFX1250-NEXT: ret i32 [[VAL]]169;170 %val = atomicrmw volatile xchg ptr addrspace(5) %addr, i32 %in acq_rel171 ret i32 %val172}173 174define i16 @system_atomicrmw_xchg_acq_rel_i16(ptr addrspace(5) %addr, i16 %in) {175; GFX1200-LABEL: define i16 @system_atomicrmw_xchg_acq_rel_i16(176; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], i16 [[IN:%.*]]) #[[ATTR0]] {177; GFX1200-NEXT: [[TMP1:%.*]] = load i16, ptr addrspace(5) [[ADDR]], align 2178; GFX1200-NEXT: store i16 [[IN]], ptr addrspace(5) [[ADDR]], align 2179; GFX1200-NEXT: ret i16 [[TMP1]]180;181; GFX1250-LABEL: define i16 @system_atomicrmw_xchg_acq_rel_i16(182; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], i16 [[IN:%.*]]) #[[ATTR0]] {183; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr184; GFX1250-NEXT: [[VAL:%.*]] = atomicrmw volatile xchg ptr [[SCRATCH_ASCAST]], i16 [[IN]] acq_rel, align 2185; GFX1250-NEXT: ret i16 [[VAL]]186;187 %val = atomicrmw volatile xchg ptr addrspace(5) %addr, i16 %in acq_rel188 ret i16 %val189}190 191define half @system_atomicrmw_fmax_acq_rel_half(ptr addrspace(5) %addr, half %in) {192; GFX1200-LABEL: define half @system_atomicrmw_fmax_acq_rel_half(193; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], half [[IN:%.*]]) #[[ATTR0]] {194; GFX1200-NEXT: [[TMP1:%.*]] = load half, ptr addrspace(5) [[ADDR]], align 2195; GFX1200-NEXT: [[TMP2:%.*]] = call half @llvm.maxnum.f16(half [[TMP1]], half [[IN]])196; GFX1200-NEXT: store half [[TMP2]], ptr addrspace(5) [[ADDR]], align 2197; GFX1200-NEXT: ret half [[TMP1]]198;199; GFX1250-LABEL: define half @system_atomicrmw_fmax_acq_rel_half(200; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], half [[IN:%.*]]) #[[ATTR0]] {201; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr202; GFX1250-NEXT: [[VAL:%.*]] = atomicrmw volatile fmax ptr [[SCRATCH_ASCAST]], half [[IN]] acq_rel, align 2203; GFX1250-NEXT: ret half [[VAL]]204;205 %val = atomicrmw volatile fmax ptr addrspace(5) %addr, half %in acq_rel206 ret half %val207}208 209define float @system_atomicrmw_fminimum_acq_rel_float(ptr addrspace(5) %addr, float %in) {210; GFX1200-LABEL: define float @system_atomicrmw_fminimum_acq_rel_float(211; GFX1200-SAME: ptr addrspace(5) [[ADDR:%.*]], float [[IN:%.*]]) #[[ATTR0]] {212; GFX1200-NEXT: [[TMP1:%.*]] = load float, ptr addrspace(5) [[ADDR]], align 4213; GFX1200-NEXT: [[TMP2:%.*]] = call float @llvm.minimum.f32(float [[TMP1]], float [[IN]])214; GFX1200-NEXT: store float [[TMP2]], ptr addrspace(5) [[ADDR]], align 4215; GFX1200-NEXT: ret float [[TMP1]]216;217; GFX1250-LABEL: define float @system_atomicrmw_fminimum_acq_rel_float(218; GFX1250-SAME: ptr addrspace(5) [[ADDR:%.*]], float [[IN:%.*]]) #[[ATTR0]] {219; GFX1250-NEXT: [[SCRATCH_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ADDR]] to ptr220; GFX1250-NEXT: [[VAL:%.*]] = atomicrmw volatile fminimum ptr [[SCRATCH_ASCAST]], float [[IN]] acq_rel, align 4, !nontemporal [[META1]]221; GFX1250-NEXT: ret float [[VAL]]222;223 %val = atomicrmw volatile fminimum ptr addrspace(5) %addr, float %in acq_rel, !nontemporal !0224 ret float %val225}226 227!0 = !{}228!1 = !{i32 1}229;.230; GFX1200: [[META0]] = !{i32 1}231; GFX1200: [[META1]] = !{}232;.233; GFX1250: [[META0]] = !{i32 1}234; GFX1250: [[META1]] = !{}235;.236