- 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
763 lines
20 KiB
LLVM
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
|
|
}
|