
- Instead of lowering float/double ISD::ATOMIC_LOAD / ISD::ATOMIC_STORE nodes to regular LOAD/STORE nodes, make them legal and select those nodes properly instead. This avoids exposing them to the DAGCombiner. - AtomicExpand pass no longer casts float/double atomic load/stores to integer (FP128 is still casted).
740 lines
20 KiB
LLVM
740 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(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, .LCPI49_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(<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
|
|
}
|