| ; 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 |
| } |