| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 |
| ; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \ |
| ; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s |
| |
| define float @ldexp_f32(i8 zeroext %x) { |
| ; CHECK-LABEL: ldexp_f32: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -32(r1) |
| ; CHECK-NEXT: std r0, 48(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: vspltisw v2, 1 |
| ; CHECK-NEXT: mr r4, r3 |
| ; CHECK-NEXT: xvcvsxwdp vs1, v2 |
| ; CHECK-NEXT: # kill: def $f1 killed $f1 killed $vsl1 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: addi r1, r1, 32 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %zext = zext i8 %x to i32 |
| %ldexp = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 %zext) |
| ret float %ldexp |
| } |
| |
| define double @ldexp_f64(i8 zeroext %x) { |
| ; CHECK-LABEL: ldexp_f64: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -32(r1) |
| ; CHECK-NEXT: std r0, 48(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: vspltisw v2, 1 |
| ; CHECK-NEXT: mr r4, r3 |
| ; CHECK-NEXT: xvcvsxwdp vs1, v2 |
| ; CHECK-NEXT: # kill: def $f1 killed $f1 killed $vsl1 |
| ; CHECK-NEXT: bl ldexp |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: addi r1, r1, 32 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %zext = zext i8 %x to i32 |
| %ldexp = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 %zext) |
| ret double %ldexp |
| } |
| |
| define <2 x float> @ldexp_v2f32(<2 x float> %val, <2 x i32> %exp) { |
| ; CHECK-LABEL: ldexp_v2f32: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -80(r1) |
| ; CHECK-NEXT: std r0, 96(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 80 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: .cfi_offset v29, -48 |
| ; CHECK-NEXT: .cfi_offset v30, -32 |
| ; CHECK-NEXT: .cfi_offset v31, -16 |
| ; CHECK-NEXT: xxsldwi vs0, v2, v2, 3 |
| ; CHECK-NEXT: li r3, 0 |
| ; CHECK-NEXT: stxv v29, 32(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: xscvspdpn f1, vs0 |
| ; CHECK-NEXT: vextuwrx r4, r3, v3 |
| ; CHECK-NEXT: stxv v30, 48(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: stxv v31, 64(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: vmr v31, v3 |
| ; CHECK-NEXT: vmr v30, v2 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: xxswapd vs0, v30 |
| ; CHECK-NEXT: li r3, 4 |
| ; CHECK-NEXT: xscvdpspn v29, f1 |
| ; CHECK-NEXT: xscvspdpn f1, vs0 |
| ; CHECK-NEXT: vextuwrx r4, r3, v31 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: xscvdpspn vs0, f1 |
| ; CHECK-NEXT: lxv v31, 64(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: lxv v30, 48(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: xxmrghw v2, vs0, v29 |
| ; CHECK-NEXT: lxv v29, 32(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: addi r1, r1, 80 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp) |
| ret <2 x float> %1 |
| } |
| |
| define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) { |
| ; CHECK-LABEL: ldexp_v4f32: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -96(r1) |
| ; CHECK-NEXT: std r0, 112(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 96 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: .cfi_offset v28, -64 |
| ; CHECK-NEXT: .cfi_offset v29, -48 |
| ; CHECK-NEXT: .cfi_offset v30, -32 |
| ; CHECK-NEXT: .cfi_offset v31, -16 |
| ; CHECK-NEXT: li r3, 12 |
| ; CHECK-NEXT: xscvspdpn f1, v2 |
| ; CHECK-NEXT: stxv v28, 32(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: stxv v29, 48(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: stxv v30, 64(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: stxv v31, 80(r1) # 16-byte Folded Spill |
| ; CHECK-NEXT: vmr v31, v3 |
| ; CHECK-NEXT: vmr v30, v2 |
| ; CHECK-NEXT: vextuwrx r4, r3, v3 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: xxswapd vs0, v30 |
| ; CHECK-NEXT: li r3, 4 |
| ; CHECK-NEXT: xscpsgndp v29, f1, f1 |
| ; CHECK-NEXT: xscvspdpn f1, vs0 |
| ; CHECK-NEXT: vextuwrx r4, r3, v31 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: # kill: def $f1 killed $f1 def $vsl1 |
| ; CHECK-NEXT: xxmrghd vs0, v29, vs1 |
| ; CHECK-NEXT: li r3, 0 |
| ; CHECK-NEXT: vextuwrx r4, r3, v31 |
| ; CHECK-NEXT: xvcvdpsp v28, vs0 |
| ; CHECK-NEXT: xxsldwi vs0, v30, v30, 3 |
| ; CHECK-NEXT: xscvspdpn f1, vs0 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: xxsldwi vs0, v30, v30, 1 |
| ; CHECK-NEXT: xscpsgndp v29, f1, f1 |
| ; CHECK-NEXT: mfvsrwz r4, v31 |
| ; CHECK-NEXT: xscvspdpn f1, vs0 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: # kill: def $f1 killed $f1 def $vsl1 |
| ; CHECK-NEXT: xxmrghd vs0, vs1, v29 |
| ; CHECK-NEXT: lxv v31, 80(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: lxv v30, 64(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: lxv v29, 48(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: xvcvdpsp v2, vs0 |
| ; CHECK-NEXT: vmrgew v2, v28, v2 |
| ; CHECK-NEXT: lxv v28, 32(r1) # 16-byte Folded Reload |
| ; CHECK-NEXT: addi r1, r1, 96 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %1 = call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> %val, <4 x i32> %exp) |
| ret <4 x float> %1 |
| } |
| |
| define half @ldexp_f16(half %arg0, i32 %arg1) { |
| ; CHECK-LABEL: ldexp_f16: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -32(r1) |
| ; CHECK-NEXT: std r0, 48(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: xscvdphp f0, f1 |
| ; CHECK-NEXT: clrldi r4, r4, 32 |
| ; CHECK-NEXT: mffprwz r3, f0 |
| ; CHECK-NEXT: clrlwi r3, r3, 16 |
| ; CHECK-NEXT: mtfprwz f0, r3 |
| ; CHECK-NEXT: xscvhpdp f1, f0 |
| ; CHECK-NEXT: bl ldexpf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: addi r1, r1, 32 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %ldexp = call half @llvm.ldexp.f16.i32(half %arg0, i32 %arg1) |
| ret half %ldexp |
| } |
| |
| define ppc_fp128 @ldexp_fp128(ppc_fp128 %arg0, i32 %arg1) { |
| ; CHECK-LABEL: ldexp_fp128: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: mflr r0 |
| ; CHECK-NEXT: stdu r1, -32(r1) |
| ; CHECK-NEXT: std r0, 48(r1) |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 |
| ; CHECK-NEXT: .cfi_offset lr, 16 |
| ; CHECK-NEXT: clrldi r5, r5, 32 |
| ; CHECK-NEXT: bl ldexpl |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: addi r1, r1, 32 |
| ; CHECK-NEXT: ld r0, 16(r1) |
| ; CHECK-NEXT: mtlr r0 |
| ; CHECK-NEXT: blr |
| %ldexp = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 %arg0, i32 %arg1) |
| ret ppc_fp128 %ldexp |
| } |
| |
| declare double @llvm.ldexp.f64.i32(double, i32) #0 |
| declare float @llvm.ldexp.f32.i32(float, i32) #0 |
| declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #0 |
| declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>) #0 |
| declare half @llvm.ldexp.f16.i32(half, i32) #0 |
| declare ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128, i32) #0 |
| |
| attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } |