Files
llvm-project/llvm/test/CodeGen/SystemZ/atomic-memops.ll
Jonas Paulsson c999e9a4fe [SystemZ] Support fp16 vector ABI and basic codegen. (#171066)
- Make v8f16 a legal type so that arguments can be passed in vector
registers. Handle fp16 vectors so that they have the same ABI as other
fp vectors.

- Set the preferred vector action for fp16 vectors to "split". This will
scalarize all operations, which is not always necessary (like with
memory operations), but it avoids the superfluous operations that result
after first widening and then scalarizing a narrow vector (like v4f16).

Fixes #168992
2026-01-26 13:42:25 -06:00

763 lines
20 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z16 | FileCheck %s
; Sign-extending atomic loads.
define void @f1(ptr %src, ptr %dst) {
; CHECK-LABEL: f1:
; CHECK: # %bb.0:
; CHECK-NEXT: lb %r0, 0(%r2)
; CHECK-NEXT: sth %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%s = sext i8 %b to i16
store volatile i16 %s, ptr %dst
ret void
}
define void @f2(ptr %src, ptr %dst) {
; CHECK-LABEL: f2:
; CHECK: # %bb.0:
; CHECK-NEXT: lb %r0, 0(%r2)
; CHECK-NEXT: st %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%s = sext i8 %b to i32
store volatile i32 %s, ptr %dst
ret void
}
define void @f3(ptr %src, ptr %dst) {
; CHECK-LABEL: f3:
; CHECK: # %bb.0:
; CHECK-NEXT: lgb %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%s = sext i8 %b to i64
store volatile i64 %s, ptr %dst
ret void
}
define void @f4(ptr %src, ptr %dst) {
; CHECK-LABEL: f4:
; CHECK: # %bb.0:
; CHECK-NEXT: lh %r0, 0(%r2)
; CHECK-NEXT: st %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i16, ptr %src seq_cst, align 2
%s = sext i16 %b to i32
store volatile i32 %s, ptr %dst
ret void
}
define void @f5(ptr %src, ptr %dst) {
; CHECK-LABEL: f5:
; CHECK: # %bb.0:
; CHECK-NEXT: lgh %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i16, ptr %src seq_cst, align 2
%s = sext i16 %b to i64
store volatile i64 %s, ptr %dst
ret void
}
define void @f6(ptr %src, ptr %dst) {
; CHECK-LABEL: f6:
; CHECK: # %bb.0:
; CHECK-NEXT: lgf %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i32, ptr %src seq_cst, align 4
%s = sext i32 %b to i64
store volatile i64 %s, ptr %dst
ret void
}
; Zero-extending atomic loads.
define void @f7(ptr %src, ptr %dst) {
; CHECK-LABEL: f7:
; CHECK: # %bb.0:
; CHECK-NEXT: llc %r0, 0(%r2)
; CHECK-NEXT: sth %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%z = zext i8 %b to i16
store volatile i16 %z, ptr %dst
ret void
}
define void @f8(ptr %src, ptr %dst) {
; CHECK-LABEL: f8:
; CHECK: # %bb.0:
; CHECK-NEXT: llc %r0, 0(%r2)
; CHECK-NEXT: st %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%z = zext i8 %b to i32
store volatile i32 %z, ptr %dst
ret void
}
define void @f9(ptr %src, ptr %dst) {
; CHECK-LABEL: f9:
; CHECK: # %bb.0:
; CHECK-NEXT: llgc %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%z = zext i8 %b to i64
store volatile i64 %z, ptr %dst
ret void
}
define void @f10(ptr %src, ptr %dst) {
; CHECK-LABEL: f10:
; CHECK: # %bb.0:
; CHECK-NEXT: llh %r0, 0(%r2)
; CHECK-NEXT: st %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i16, ptr %src seq_cst, align 2
%z = zext i16 %b to i32
store volatile i32 %z, ptr %dst
ret void
}
define void @f11(ptr %src, ptr %dst) {
; CHECK-LABEL: f11:
; CHECK: # %bb.0:
; CHECK-NEXT: llgh %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i16, ptr %src seq_cst, align 2
%z = zext i16 %b to i64
store volatile i64 %z, ptr %dst
ret void
}
define void @f12(ptr %src, ptr %dst) {
; CHECK-LABEL: f12:
; CHECK: # %bb.0:
; CHECK-NEXT: llgf %r0, 0(%r2)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i32, ptr %src seq_cst, align 4
%z = zext i32 %b to i64
store volatile i64 %z, ptr %dst
ret void
}
; reg/mem
define i64 @f13(i64 %a, ptr %src) {
; CHECK-LABEL: f13:
; CHECK: # %bb.0:
; CHECK-NEXT: ag %r2, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i64, ptr %src seq_cst, align 8
%add = add i64 %a, %b
ret i64 %add
}
; reg/mem op with extension from memory.
define i64 @f14(i64 %a, ptr %src) {
; CHECK-LABEL: f14:
; CHECK: # %bb.0:
; CHECK-NEXT: slgf %r2, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i32, ptr %src seq_cst, align 4
%bext = zext i32 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
define float @f15(float %f1, ptr %ptr, float %acc) {
; CHECK-LABEL: f15:
; CHECK: # %bb.0:
; CHECK-NEXT: maeb %f2, %f0, 0(%r2)
; CHECK-NEXT: ldr %f0, %f2
; CHECK-NEXT: br %r14
%f2 = load atomic float, ptr %ptr seq_cst, align 4
%res = call float @llvm.fma.f32 (float %f1, float %f2, float %acc)
ret float %res
}
declare float @llvm.fma.f32(float %f1, float %f2, float %f3)
define double @f15_b(ptr %src) {
; CHECK-LABEL: f15_b:
; CHECK: # %bb.0:
; CHECK-NEXT: ldeb %f0, 0(%r2)
; CHECK-NEXT: br %r14
%V = load atomic float, ptr %src seq_cst, align 4
%Res = fpext float %V to double
ret double %Res
}
define fp128 @f15_c(ptr %src) {
; CHECK-LABEL: f15_c:
; CHECK: # %bb.0:
; CHECK-NEXT: lde %f0, 0(%r3)
; CHECK-NEXT: ldebr %f0, %f0
; CHECK-NEXT: wflld %v0, %f0
; CHECK-NEXT: vst %v0, 0(%r2), 3
; CHECK-NEXT: br %r14
%V = load atomic float, ptr %src seq_cst, align 4
%Res = fpext float %V to fp128
ret fp128 %Res
}
define fp128 @f15_d(ptr %src) {
; CHECK-LABEL: f15_d:
; CHECK: # %bb.0:
; CHECK-NEXT: ld %f0, 0(%r3)
; CHECK-NEXT: wflld %v0, %f0
; CHECK-NEXT: vst %v0, 0(%r2), 3
; CHECK-NEXT: br %r14
%V = load atomic double, ptr %src seq_cst, align 8
%Res = fpext double %V to fp128
ret fp128 %Res
}
; Do it twice for good measure given the involved DAG combines.
define void @f16(ptr %src, ptr %dst) {
; CHECK-LABEL: f16:
; CHECK: # %bb.0:
; CHECK-NEXT: llgc %r0, 0(%r2)
; CHECK-NEXT: lgbr %r1, %r0
; CHECK-NEXT: stg %r1, 0(%r3)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: llgc %r0, 0(%r2)
; CHECK-NEXT: lgbr %r1, %r0
; CHECK-NEXT: stg %r1, 0(%r3)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%s = sext i8 %b to i64
%z = zext i8 %b to i64
store volatile i64 %s, ptr %dst
store volatile i64 %z, ptr %dst
%b2 = load atomic i8, ptr %src seq_cst, align 1
%s2 = sext i8 %b2 to i64
%z2 = zext i8 %b2 to i64
store volatile i64 %s2, ptr %dst
store volatile i64 %z2, ptr %dst
ret void
}
define void @f16_b(ptr %src, ptr %dst) {
; CHECK-LABEL: f16_b:
; CHECK: # %bb.0:
; CHECK-NEXT: lgb %r0, 0(%r2)
; CHECK-NEXT: sth %r0, 0(%r3)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%s = sext i8 %b to i16
store volatile i16 %s, ptr %dst
%s2 = sext i8 %b to i64
store volatile i64 %s2, ptr %dst
ret void
}
define void @f16_c(ptr %src, ptr %dst) {
; CHECK-LABEL: f16_c:
; CHECK: # %bb.0:
; CHECK-NEXT: llgc %r0, 0(%r2)
; CHECK-NEXT: sth %r0, 0(%r3)
; CHECK-NEXT: stg %r0, 0(%r3)
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%z = zext i8 %b to i16
store volatile i16 %z, ptr %dst
%z2 = zext i8 %b to i64
store volatile i64 %z2, ptr %dst
ret void
}
; Check that two i8 loads use a reg/reg op.
define i8 @f16_d(ptr %src, ptr %src2) {
; CHECK-LABEL: f16_d:
; CHECK: # %bb.0:
; CHECK-NEXT: lb %r2, 0(%r2)
; CHECK-NEXT: lb %r0, 0(%r3)
; CHECK-NEXT: ar %r2, %r0
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%b2 = load atomic i8, ptr %src2 seq_cst, align 1
%add = add i8 %b, %b2
ret i8 %add
}
; Binary operations on a byte in memory, with an atomic load.
define void @f17(ptr %ptr) {
; CHECK-LABEL: f17:
; CHECK: # %bb.0:
; CHECK-NEXT: ni 0(%r2), 1
; CHECK-NEXT: br %r14
%val = load atomic i8, ptr %ptr seq_cst, align 1
%xor = and i8 %val, -255
store i8 %xor, ptr %ptr
ret void
}
define void @f18(ptr %src) {
; CHECK-LABEL: f18:
; CHECK: # %bb.0:
; CHECK-NEXT: oiy 4096(%r2), 1
; CHECK-NEXT: br %r14
%ptr = getelementptr i8, ptr %src, i64 4096
%val = load atomic i8, ptr %ptr seq_cst, align 1
%xor = or i8 %val, -255
store i8 %xor, ptr %ptr
ret void
}
define void @f19(ptr %src) {
; CHECK-LABEL: f19:
; CHECK: # %bb.0:
; CHECK-NEXT: xi 4095(%r2), 1
; CHECK-NEXT: br %r14
%ptr = getelementptr i8, ptr %src, i64 4095
%val = load atomic i8, ptr %ptr seq_cst, align 1
%xor = xor i8 %val, -255
store i8 %xor, ptr %ptr
ret void
}
; TM
define double @f20(ptr %src, double %a, double %b) {
; CHECK-LABEL: f20:
; CHECK: # %bb.0:
; CHECK-NEXT: tm 0(%r2), 1
; CHECK-NEXT: je .LBB25_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: ldr %f2, %f0
; CHECK-NEXT: .LBB25_2:
; CHECK-NEXT: ldr %f0, %f2
; CHECK-NEXT: br %r14
%byte = load atomic i8, ptr %src seq_cst, align 1
%and = and i8 %byte, 1
%cmp = icmp eq i8 %and, 0
%res = select i1 %cmp, double %b, double %a
ret double %res
}
; vector load and replicate
define void @f21(ptr %src, ptr %dst) {
; CHECK-LABEL: f21:
; CHECK: # %bb.0:
; CHECK-NEXT: vlrepb %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic i8, ptr %src seq_cst, align 1
%v = insertelement <16 x i8> undef, i8 %b, i32 1
store volatile <16 x i8> %v, ptr %dst
ret void
}
define void @f22(ptr %src, ptr %dst) {
; CHECK-LABEL: f22:
; CHECK: # %bb.0:
; CHECK-NEXT: vlreph %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic i16, ptr %src seq_cst, align 2
%v = insertelement <8 x i16> undef, i16 %b, i32 1
store volatile <8 x i16> %v, ptr %dst
ret void
}
define void @f23(ptr %src, ptr %dst) {
; CHECK-LABEL: f23:
; CHECK: # %bb.0:
; CHECK-NEXT: vlrepf %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic i32, ptr %src seq_cst, align 4
%v = insertelement <4 x i32> undef, i32 %b, i32 2
store volatile <4 x i32> %v, ptr %dst
ret void
}
define void @f24(ptr %src, ptr %dst) {
; CHECK-LABEL: f24:
; CHECK: # %bb.0:
; CHECK-NEXT: vlrepg %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic i64, ptr %src seq_cst, align 8
%v = insertelement <2 x i64> undef, i64 %b, i32 0
store volatile <2 x i64> %v, ptr %dst
ret void
}
define void @f25_half(ptr %src, ptr %dst) {
; CHECK-LABEL: f25_half:
; CHECK: # %bb.0:
; CHECK-NEXT: vlreph %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic half, ptr %src seq_cst, align 2
%v = insertelement <8 x half> undef, half %b, i32 1
store volatile <8 x half> %v, ptr %dst
ret void
}
define void @f25(ptr %src, ptr %dst) {
; CHECK-LABEL: f25:
; CHECK: # %bb.0:
; CHECK-NEXT: vlrepf %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic float, ptr %src seq_cst, align 4
%v = insertelement <4 x float> undef, float %b, i32 1
store volatile <4 x float> %v, ptr %dst
ret void
}
; Do *not* use vlrep for an extending load.
define <4 x i32> @f25_c(ptr %ptr) {
; CHECK-LABEL: f25_c:
; CHECK: # %bb.0:
; CHECK-NEXT: lb %r0, 0(%r2)
; CHECK-NEXT: vlvgp %v0, %r0, %r0
; CHECK-NEXT: vrepf %v24, %v0, 1
; CHECK-NEXT: br %r14
%L = load atomic i8, ptr %ptr seq_cst, align 4
%S = sext i8 %L to i32
%val = insertelement <4 x i32> undef, i32 %S, i32 0
%ret = shufflevector <4 x i32> %val, <4 x i32> undef,
<4 x i32> zeroinitializer
ret <4 x i32> %ret
}
; Do *not* use vlrep if there is another scalar use.
define <4 x i32> @f25_d(ptr %ptr, ptr %dst) {
; CHECK-LABEL: f25_d:
; CHECK: # %bb.0:
; CHECK-NEXT: l %r0, 0(%r2)
; CHECK-NEXT: vlvgp %v0, %r0, %r0
; CHECK-NEXT: vrepf %v24, %v0, 1
; CHECK-NEXT: st %r0, 0(%r3)
; CHECK-NEXT: br %r14
%L = load atomic i32, ptr %ptr seq_cst, align 4
store i32 %L, ptr %dst, align 4
%val = insertelement <4 x i32> undef, i32 %L, i32 0
%ret = shufflevector <4 x i32> %val, <4 x i32> undef,
<4 x i32> zeroinitializer
ret <4 x i32> %ret
}
define void @f26(ptr %src, ptr %dst) {
; CHECK-LABEL: f26:
; CHECK: # %bb.0:
; CHECK-NEXT: vlrepg %v0, 0(%r2)
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%b = load atomic double, ptr %src seq_cst, align 8
%v = insertelement <2 x double> undef, double %b, i32 0
store volatile <2 x double> %v, ptr %dst
ret void
}
; Vector Load logical element and zero.
define <16 x i8> @f27(ptr %ptr) {
; CHECK-LABEL: f27:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezb %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic i8, ptr %ptr seq_cst, align 1
%ret = insertelement <16 x i8> zeroinitializer, i8 %val, i32 7
ret <16 x i8> %ret
}
define <8 x i16> @f28(ptr %ptr) {
; CHECK-LABEL: f28:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezh %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic i16, ptr %ptr seq_cst, align 2
%ret = insertelement <8 x i16> zeroinitializer, i16 %val, i32 3
ret <8 x i16> %ret
}
define <4 x i32> @f29(ptr %ptr) {
; CHECK-LABEL: f29:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezf %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic i32, ptr %ptr seq_cst, align 4
%ret = insertelement <4 x i32> zeroinitializer, i32 %val, i32 1
ret <4 x i32> %ret
}
define <2 x i64> @f30(ptr %ptr) {
; CHECK-LABEL: f30:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezg %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic i64, ptr %ptr seq_cst, align 8
%ret = insertelement <2 x i64> zeroinitializer, i64 %val, i32 0
ret <2 x i64> %ret
}
define <4 x i32> @f31(ptr %ptr) {
; CHECK-LABEL: f31:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezlf %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic i32, ptr %ptr seq_cst, align 4
%ret = insertelement <4 x i32> zeroinitializer, i32 %val, i32 0
ret <4 x i32> %ret
}
define <4 x float> @f32(ptr %ptr) {
; CHECK-LABEL: f32:
; CHECK: # %bb.0:
; CHECK-NEXT: vllezlf %v24, 0(%r2)
; CHECK-NEXT: br %r14
%val = load atomic float, ptr %ptr seq_cst, align 4
%ret = insertelement <4 x float> zeroinitializer, float %val, i32 0
ret <4 x float> %ret
}
; Vector Load element.
define <16 x i8> @f33(<16 x i8> %val, ptr %ptr) {
; CHECK-LABEL: f33:
; CHECK: # %bb.0:
; CHECK-NEXT: vleb %v24, 0(%r2), 0
; CHECK-NEXT: br %r14
%element = load atomic i8, ptr %ptr seq_cst, align 1
%ret = insertelement <16 x i8> %val, i8 %element, i32 0
ret <16 x i8> %ret
}
define <8 x i16> @f34(<8 x i16> %val, ptr %ptr) {
; CHECK-LABEL: f34:
; CHECK: # %bb.0:
; CHECK-NEXT: vleh %v24, 0(%r2), 0
; CHECK-NEXT: br %r14
%element = load atomic i16, ptr %ptr seq_cst, align 2
%ret = insertelement <8 x i16> %val, i16 %element, i32 0
ret <8 x i16> %ret
}
define <4 x i32> @f35(<4 x i32> %val, ptr %ptr) {
; CHECK-LABEL: f35:
; CHECK: # %bb.0:
; CHECK-NEXT: vlef %v24, 0(%r2), 0
; CHECK-NEXT: br %r14
%element = load atomic i32, ptr %ptr seq_cst, align 4
%ret = insertelement <4 x i32> %val, i32 %element, i32 0
ret <4 x i32> %ret
}
define <2 x i64> @f36(<2 x i64> %val, ptr %ptr) {
; CHECK-LABEL: f36:
; CHECK: # %bb.0:
; CHECK-NEXT: vleg %v24, 0(%r2), 0
; CHECK-NEXT: br %r14
%element = load atomic i64, ptr %ptr seq_cst, align 8
%ret = insertelement <2 x i64> %val, i64 %element, i32 0
ret <2 x i64> %ret
}
; Test operation on memory involving atomic load and store.
define void @f39(ptr %ptr) {
; CHECK-LABEL: f39:
; CHECK: # %bb.0:
; CHECK-NEXT: oi 0(%r2), 1
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%val = load atomic i8, ptr %ptr seq_cst, align 1
%or = or i8 %val, -255
store atomic i8 %or, ptr %ptr seq_cst, align 1
ret void
}
; Some atomic stores of immediates.
define void @f40(ptr %ptr) {
; CHECK-LABEL: f40:
; CHECK: # %bb.0:
; CHECK-NEXT: mvi 0(%r2), 128
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
store atomic i8 128, ptr %ptr seq_cst, align 1
ret void
}
define void @f41(ptr %ptr) {
; CHECK-LABEL: f41:
; CHECK: # %bb.0:
; CHECK-NEXT: mvhi 0(%r2), -1
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
store atomic i32 4294967295, ptr %ptr seq_cst, align 4
ret void
}
define void @f42(ptr %ptr) {
; CHECK-LABEL: f42:
; CHECK: # %bb.0:
; CHECK-NEXT: mvhi 0(%r2), -1
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
store atomic i32 4294967295, ptr %ptr seq_cst, align 4
ret void
}
define void @f43(ptr %ptr) {
; CHECK-LABEL: f43:
; CHECK: # %bb.0:
; CHECK-NEXT: llihl %r0, 255
; CHECK-NEXT: oilf %r0, 4294967295
; CHECK-NEXT: stg %r0, 0(%r2)
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
store atomic i64 1099511627775, ptr %ptr seq_cst, align 8
ret void
}
define void @f44(ptr %ptr) {
; CHECK-LABEL: f44:
; CHECK: # %bb.0:
; CHECK-NEXT: larl %r1, .LCPI50_0
; CHECK-NEXT: ld %f0, 0(%r1)
; CHECK-NEXT: std %f0, 0(%r2)
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
store atomic double 0x3ff0000020000000, ptr %ptr seq_cst, align 8
ret void
}
; Vector Store Element.
define void @f45(<16 x i8> %val, ptr %ptr) {
; CHECK-LABEL: f45:
; CHECK: # %bb.0:
; CHECK-NEXT: vsteb %v24, 0(%r2), 0
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <16 x i8> %val, i32 0
store atomic i8 %element, ptr %ptr seq_cst, align 1
ret void
}
define void @f46(<8 x i16> %val, ptr %base) {
; CHECK-LABEL: f46:
; CHECK: # %bb.0:
; CHECK-NEXT: vsteh %v24, 4094(%r2), 5
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%ptr = getelementptr i16, ptr %base, i32 2047
%element = extractelement <8 x i16> %val, i32 5
store atomic i16 %element, ptr %ptr seq_cst, align 2
ret void
}
define void @f47(<4 x i32> %val, ptr %ptr) {
; CHECK-LABEL: f47:
; CHECK: # %bb.0:
; CHECK-NEXT: vstef %v24, 0(%r2), 3
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <4 x i32> %val, i32 3
store atomic i32 %element, ptr %ptr seq_cst, align 4
ret void
}
define void @f48(<2 x i64> %val, ptr %ptr) {
; CHECK-LABEL: f48:
; CHECK: # %bb.0:
; CHECK-NEXT: vsteg %v24, 0(%r2), 1
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <2 x i64> %val, i32 1
store atomic i64 %element, ptr %ptr seq_cst, align 8
ret void
}
define void @f49_half(<8 x half> %val, ptr %ptr) {
; CHECK-LABEL: f49_half:
; CHECK: # %bb.0:
; CHECK-NEXT: vsteh %v24, 0(%r2), 0
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <8 x half> %val, i32 0
store atomic half %element, ptr %ptr seq_cst, align 4
ret void
}
define void @f49(<4 x float> %val, ptr %ptr) {
; CHECK-LABEL: f49:
; CHECK: # %bb.0:
; CHECK-NEXT: vstef %v24, 0(%r2), 0
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <4 x float> %val, i32 0
store atomic float %element, ptr %ptr seq_cst, align 4
ret void
}
define void @f50(<2 x double> %val, ptr %ptr) {
; CHECK-LABEL: f50:
; CHECK: # %bb.0:
; CHECK-NEXT: vsteg %v24, 0(%r2), 1
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%element = extractelement <2 x double> %val, i32 1
store atomic double %element, ptr %ptr seq_cst, align 8
ret void
}
define void @f51(ptr %src, ptr %dst) {
; CHECK-LABEL: f51:
; CHECK: # %bb.0:
; CHECK-NEXT: lpq %r0, 0(%r2)
; CHECK-NEXT: vlvgp %v0, %r0, %r1
; CHECK-NEXT: vgmf %v1, 2, 8
; CHECK-NEXT: aebr %f0, %f1
; CHECK-NEXT: ste %f0, 0(%r3)
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%atomic-load = load atomic i128, ptr %src seq_cst, align 16
%b0 = bitcast i128 %atomic-load to <4 x float>
%vecext = extractelement <4 x float> %b0, i64 0
%add = fadd float %vecext, 1.000000e+00
store atomic float %add, ptr %dst seq_cst, align 4
ret void
}
define void @f52(ptr %src, ptr %dst) {
; CHECK-LABEL: f52:
; CHECK: # %bb.0:
; CHECK-NEXT: lpq %r0, 0(%r2)
; CHECK-NEXT: vlvgp %v0, %r0, %r1
; CHECK-NEXT: vgmg %v1, 2, 11
; CHECK-NEXT: adbr %f0, %f1
; CHECK-NEXT: std %f0, 0(%r3)
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%atomic-load = load atomic i128, ptr %src seq_cst, align 16
%b0 = bitcast i128 %atomic-load to <2 x double>
%vecext = extractelement <2 x double> %b0, i64 0
%add = fadd double %vecext, 1.000000e+00
store atomic double %add, ptr %dst seq_cst, align 8
ret void
}
define void @fun58(ptr %ptr, i64 %arg) {
; CHECK-LABEL: fun58:
; CHECK: # %bb.0:
; CHECK-NEXT: st %r3, 0(%r2)
; CHECK-NEXT: bcr 14, %r0
; CHECK-NEXT: br %r14
%res = trunc i64 %arg to i32
store atomic i32 %res, ptr %ptr seq_cst, align 4
ret void
}