| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 | |
| ; RUN: llc -mtriple=aarch64 -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVELINUX %s | |
| ; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=2 < %s -o - 2>&1 | FileCheck -check-prefixes=GISEL %s | |
| ; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVEWINDOWS %s | |
| ; RUN: llc -mtriple=aarch64-windows-msvc < %s -o - | FileCheck -check-prefixes=WINDOWS %s | |
| ; GISEL: warning: Instruction selection used fallback path for testExpIntrinsic_i16 | |
| define double @testExp(double %val, i32 %a) { | |
| ; SVE-LABEL: testExp: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: // kill: def $w0 killed $w0 def $x0 | |
| ; SVE-NEXT: sxtw x8, w0 | |
| ; SVE-NEXT: ptrue p0.d | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; SVE-NEXT: fmov d1, x8 | |
| ; SVE-NEXT: fscale z0.d, p0/m, z0.d, z1.d | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 killed $z0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExp: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: b ldexp | |
| ; | |
| ; WINDOWS-LABEL: testExp: | |
| ; WINDOWS: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: b ldexp | |
| entry: | |
| %call = tail call fast double @ldexp(double %val, i32 %a) | |
| ret double %call | |
| } | |
| declare double @ldexp(double, i32) memory(none) | |
| define double @testExpIntrinsic(double %val, i32 %a) { | |
| ; SVE-LABEL: testExpIntrinsic: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: // kill: def $w0 killed $w0 def $x0 | |
| ; SVE-NEXT: sxtw x8, w0 | |
| ; SVE-NEXT: ptrue p0.d | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; SVE-NEXT: fmov d1, x8 | |
| ; SVE-NEXT: fscale z0.d, p0/m, z0.d, z1.d | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 killed $z0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpIntrinsic: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: b ldexp | |
| ; | |
| ; WINDOWS-LABEL: testExpIntrinsic: | |
| ; WINDOWS: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: b ldexp | |
| entry: | |
| %call = tail call fast double @llvm.ldexp.f64(double %val, i32 %a) | |
| ret double %call | |
| } | |
| ; A sub-int exponent must be sign-extended to int on the libcall path; | |
| ; PromoteIntOp_ExpOp must not crash on it. | |
| define double @testExpIntrinsic_i16(double %val, i16 %a) nounwind { | |
| ; SVE-LABEL: testExpIntrinsic_i16: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; SVE-NEXT: sxth w0, w0 | |
| ; SVE-NEXT: bl ldexp | |
| ; SVE-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpIntrinsic_i16: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; GISEL-NEXT: sxth w0, w0 | |
| ; GISEL-NEXT: bl ldexp | |
| ; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; GISEL-NEXT: ret | |
| ; | |
| ; WINDOWS-LABEL: testExpIntrinsic_i16: | |
| ; WINDOWS: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; WINDOWS-NEXT: sxth w0, w0 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; WINDOWS-NEXT: ret | |
| entry: | |
| %call = tail call fast double @llvm.ldexp.f64.i16(double %val, i16 %a) | |
| ret double %call | |
| } | |
| define float @testExpf(float %val, i32 %a) { | |
| ; SVELINUX-LABEL: testExpf: | |
| ; SVELINUX: // %bb.0: // %entry | |
| ; SVELINUX-NEXT: fmov s1, w0 | |
| ; SVELINUX-NEXT: ptrue p0.s | |
| ; SVELINUX-NEXT: // kill: def $s0 killed $s0 def $z0 | |
| ; SVELINUX-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVELINUX-NEXT: // kill: def $s0 killed $s0 killed $z0 | |
| ; SVELINUX-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpf: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: b ldexpf | |
| ; | |
| ; SVEWINDOWS-LABEL: testExpf: | |
| ; SVEWINDOWS: // %bb.0: // %entry | |
| ; SVEWINDOWS-NEXT: b ldexpf | |
| ; | |
| ; WINDOWS-LABEL: testExpf: | |
| ; WINDOWS: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: b ldexpf | |
| entry: | |
| %call = tail call fast float @ldexpf(float %val, i32 %a) | |
| ret float %call | |
| } | |
| define float @testExpfIntrinsic(float %val, i32 %a) { | |
| ; SVE-LABEL: testExpfIntrinsic: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: fmov s1, w0 | |
| ; SVE-NEXT: ptrue p0.s | |
| ; SVE-NEXT: // kill: def $s0 killed $s0 def $z0 | |
| ; SVE-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVE-NEXT: // kill: def $s0 killed $s0 killed $z0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpfIntrinsic: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: b ldexpf | |
| ; | |
| ; WINDOWS-LABEL: testExpfIntrinsic: | |
| ; WINDOWS: .seh_proc testExpfIntrinsic | |
| ; WINDOWS-NEXT: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endprologue | |
| ; WINDOWS-NEXT: fcvt d0, s0 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: fcvt s0, d0 | |
| ; WINDOWS-NEXT: .seh_startepilogue | |
| ; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endepilogue | |
| ; WINDOWS-NEXT: ret | |
| ; WINDOWS-NEXT: .seh_endfunclet | |
| ; WINDOWS-NEXT: .seh_endproc | |
| entry: | |
| %call = tail call fast float @llvm.ldexp.f32(float %val, i32 %a) | |
| ret float %call | |
| } | |
| define <2 x float> @test_ldexp_v2f32_v2i32(<2 x float> %Val, <2 x i32> %Exp) { | |
| ; SVE-LABEL: test_ldexp_v2f32_v2i32: | |
| ; SVE: // %bb.0: | |
| ; SVE-NEXT: // kill: def $d1 killed $d1 def $z1 | |
| ; SVE-NEXT: mov w8, v1.s[1] | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 def $z0 | |
| ; SVE-NEXT: mov s2, v0.s[1] | |
| ; SVE-NEXT: ptrue p0.s | |
| ; SVE-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVE-NEXT: fmov s3, w8 | |
| ; SVE-NEXT: fscale z2.s, p0/m, z2.s, z3.s | |
| ; SVE-NEXT: mov v0.s[1], v2.s[0] | |
| ; SVE-NEXT: // kill: def $d0 killed $d0 killed $z0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: test_ldexp_v2f32_v2i32: | |
| ; GISEL: // %bb.0: | |
| ; GISEL-NEXT: sub sp, sp, #48 | |
| ; GISEL-NEXT: stp d9, d8, [sp, #16] // 16-byte Folded Spill | |
| ; GISEL-NEXT: str x30, [sp, #32] // 8-byte Spill | |
| ; GISEL-NEXT: .cfi_def_cfa_offset 48 | |
| ; GISEL-NEXT: .cfi_offset w30, -16 | |
| ; GISEL-NEXT: .cfi_offset b8, -24 | |
| ; GISEL-NEXT: .cfi_offset b9, -32 | |
| ; GISEL-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; GISEL-NEXT: fmov w0, s1 | |
| ; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; GISEL-NEXT: mov s8, v0.s[1] | |
| ; GISEL-NEXT: mov s9, v1.s[1] | |
| ; GISEL-NEXT: // kill: def $s0 killed $s0 killed $q0 | |
| ; GISEL-NEXT: bl ldexpf | |
| ; GISEL-NEXT: // kill: def $s0 killed $s0 def $q0 | |
| ; GISEL-NEXT: str q0, [sp] // 16-byte Spill | |
| ; GISEL-NEXT: fmov w0, s9 | |
| ; GISEL-NEXT: fmov s0, s8 | |
| ; GISEL-NEXT: bl ldexpf | |
| ; GISEL-NEXT: ldr q1, [sp] // 16-byte Reload | |
| ; GISEL-NEXT: // kill: def $s0 killed $s0 def $q0 | |
| ; GISEL-NEXT: ldp d9, d8, [sp, #16] // 16-byte Folded Reload | |
| ; GISEL-NEXT: ldr x30, [sp, #32] // 8-byte Reload | |
| ; GISEL-NEXT: mov v1.s[1], v0.s[0] | |
| ; GISEL-NEXT: fmov d0, d1 | |
| ; GISEL-NEXT: add sp, sp, #48 | |
| ; GISEL-NEXT: ret | |
| ; | |
| ; WINDOWS-LABEL: test_ldexp_v2f32_v2i32: | |
| ; WINDOWS: .seh_proc test_ldexp_v2f32_v2i32 | |
| ; WINDOWS-NEXT: // %bb.0: | |
| ; WINDOWS-NEXT: sub sp, sp, #48 | |
| ; WINDOWS-NEXT: .seh_stackalloc 48 | |
| ; WINDOWS-NEXT: str x30, [sp, #32] // 8-byte Spill | |
| ; WINDOWS-NEXT: .seh_save_reg x30, 32 | |
| ; WINDOWS-NEXT: .seh_endprologue | |
| ; WINDOWS-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; WINDOWS-NEXT: mov s2, v0.s[1] | |
| ; WINDOWS-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; WINDOWS-NEXT: stp q1, q0, [sp] // 32-byte Folded Spill | |
| ; WINDOWS-NEXT: mov w0, v1.s[1] | |
| ; WINDOWS-NEXT: fcvt d0, s2 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: ldr q1, [sp, #16] // 16-byte Reload | |
| ; WINDOWS-NEXT: fcvt s0, d0 | |
| ; WINDOWS-NEXT: fcvt d1, s1 | |
| ; WINDOWS-NEXT: str q0, [sp, #16] // 16-byte Spill | |
| ; WINDOWS-NEXT: ldr q0, [sp] // 16-byte Reload | |
| ; WINDOWS-NEXT: fmov w0, s0 | |
| ; WINDOWS-NEXT: fmov d0, d1 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: fcvt s0, d0 | |
| ; WINDOWS-NEXT: ldr q1, [sp, #16] // 16-byte Reload | |
| ; WINDOWS-NEXT: mov v0.s[1], v1.s[0] | |
| ; WINDOWS-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; WINDOWS-NEXT: .seh_startepilogue | |
| ; WINDOWS-NEXT: ldr x30, [sp, #32] // 8-byte Reload | |
| ; WINDOWS-NEXT: .seh_save_reg x30, 32 | |
| ; WINDOWS-NEXT: add sp, sp, #48 | |
| ; WINDOWS-NEXT: .seh_stackalloc 48 | |
| ; WINDOWS-NEXT: .seh_endepilogue | |
| ; WINDOWS-NEXT: ret | |
| ; WINDOWS-NEXT: .seh_endfunclet | |
| ; WINDOWS-NEXT: .seh_endproc | |
| %result = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %Val, <2 x i32> %Exp) | |
| ret <2 x float> %result | |
| } | |
| declare float @ldexpf(float, i32) memory(none) | |
| define fp128 @testExpl(fp128 %val, i32 %a) { | |
| ; SVE-LABEL: testExpl: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: b ldexpl | |
| ; | |
| ; GISEL-LABEL: testExpl: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: b ldexpl | |
| ; | |
| ; WINDOWS-LABEL: testExpl: | |
| ; WINDOWS: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: b ldexpl | |
| entry: | |
| %call = tail call fast fp128 @ldexpl(fp128 %val, i32 %a) | |
| ret fp128 %call | |
| } | |
| declare fp128 @ldexpl(fp128, i32) memory(none) | |
| define half @testExpf16(half %val, i32 %a) { | |
| ; SVE-LABEL: testExpf16: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: fcvt s0, h0 | |
| ; SVE-NEXT: fmov s1, w0 | |
| ; SVE-NEXT: ptrue p0.s | |
| ; SVE-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVE-NEXT: fcvt h0, s0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpf16: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; GISEL-NEXT: .cfi_def_cfa_offset 16 | |
| ; GISEL-NEXT: .cfi_offset w30, -16 | |
| ; GISEL-NEXT: fcvt s0, h0 | |
| ; GISEL-NEXT: bl ldexpf | |
| ; GISEL-NEXT: fcvt h0, s0 | |
| ; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; GISEL-NEXT: ret | |
| ; | |
| ; WINDOWS-LABEL: testExpf16: | |
| ; WINDOWS: .seh_proc testExpf16 | |
| ; WINDOWS-NEXT: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endprologue | |
| ; WINDOWS-NEXT: fcvt d0, h0 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: fcvt h0, d0 | |
| ; WINDOWS-NEXT: .seh_startepilogue | |
| ; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endepilogue | |
| ; WINDOWS-NEXT: ret | |
| ; WINDOWS-NEXT: .seh_endfunclet | |
| ; WINDOWS-NEXT: .seh_endproc | |
| entry: | |
| %0 = tail call fast half @llvm.ldexp.f16.i32(half %val, i32 %a) | |
| ret half %0 | |
| } | |
| define bfloat @testExpbf16(bfloat %val, i32 %a) { | |
| ; SVE-LABEL: testExpbf16: | |
| ; SVE: // %bb.0: // %entry | |
| ; SVE-NEXT: // kill: def $h0 killed $h0 def $d0 | |
| ; SVE-NEXT: fmov s1, w0 | |
| ; SVE-NEXT: ptrue p0.s | |
| ; SVE-NEXT: shll v0.4s, v0.4h, #16 | |
| ; SVE-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVE-NEXT: fmov w8, s0 | |
| ; SVE-NEXT: fcmp s0, s0 | |
| ; SVE-NEXT: orr w9, w8, #0x400000 | |
| ; SVE-NEXT: csel w8, w9, w8, vs | |
| ; SVE-NEXT: lsr w8, w8, #16 | |
| ; SVE-NEXT: fmov s0, w8 | |
| ; SVE-NEXT: // kill: def $h0 killed $h0 killed $s0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: testExpbf16: | |
| ; GISEL: // %bb.0: // %entry | |
| ; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; GISEL-NEXT: .cfi_def_cfa_offset 16 | |
| ; GISEL-NEXT: .cfi_offset w30, -16 | |
| ; GISEL-NEXT: // kill: def $h0 killed $h0 def $d0 | |
| ; GISEL-NEXT: shll v0.4s, v0.4h, #16 | |
| ; GISEL-NEXT: // kill: def $s0 killed $s0 killed $q0 | |
| ; GISEL-NEXT: bl ldexpf | |
| ; GISEL-NEXT: fmov w9, s0 | |
| ; GISEL-NEXT: mov w8, #32767 // =0x7fff | |
| ; GISEL-NEXT: ubfx w10, w9, #16, #1 | |
| ; GISEL-NEXT: add w8, w9, w8 | |
| ; GISEL-NEXT: add w8, w8, w10 | |
| ; GISEL-NEXT: lsr w8, w8, #16 | |
| ; GISEL-NEXT: fmov s0, w8 | |
| ; GISEL-NEXT: // kill: def $h0 killed $h0 killed $s0 | |
| ; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; GISEL-NEXT: ret | |
| ; | |
| ; WINDOWS-LABEL: testExpbf16: | |
| ; WINDOWS: .seh_proc testExpbf16 | |
| ; WINDOWS-NEXT: // %bb.0: // %entry | |
| ; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endprologue | |
| ; WINDOWS-NEXT: // kill: def $h0 killed $h0 def $d0 | |
| ; WINDOWS-NEXT: shll v0.4s, v0.4h, #16 | |
| ; WINDOWS-NEXT: fcvt d0, s0 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: fcvtxn s0, d0 | |
| ; WINDOWS-NEXT: mov w8, #32767 // =0x7fff | |
| ; WINDOWS-NEXT: fmov w9, s0 | |
| ; WINDOWS-NEXT: ubfx w10, w9, #16, #1 | |
| ; WINDOWS-NEXT: add w8, w9, w8 | |
| ; WINDOWS-NEXT: add w8, w10, w8 | |
| ; WINDOWS-NEXT: lsr w8, w8, #16 | |
| ; WINDOWS-NEXT: fmov s0, w8 | |
| ; WINDOWS-NEXT: // kill: def $h0 killed $h0 killed $s0 | |
| ; WINDOWS-NEXT: .seh_startepilogue | |
| ; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; WINDOWS-NEXT: .seh_save_reg_x x30, 16 | |
| ; WINDOWS-NEXT: .seh_endepilogue | |
| ; WINDOWS-NEXT: ret | |
| ; WINDOWS-NEXT: .seh_endfunclet | |
| ; WINDOWS-NEXT: .seh_endproc | |
| entry: | |
| %0 = tail call fast bfloat @llvm.ldexp.bf16.i32(bfloat %val, i32 %a) | |
| ret bfloat %0 | |
| } | |
| ; The v1f16 result is scalarized but the v1i32 exponent is widened, so the | |
| ; exponent was never scalarized. | |
| define <1 x half> @test_ldexp_v1f16_v1i32(<1 x half> %val, <1 x i32> %exp) nounwind { | |
| ; SVE-LABEL: test_ldexp_v1f16_v1i32: | |
| ; SVE: // %bb.0: | |
| ; SVE-NEXT: fcvt s0, h0 | |
| ; SVE-NEXT: ptrue p0.s | |
| ; SVE-NEXT: // kill: def $d1 killed $d1 def $z1 | |
| ; SVE-NEXT: fscale z0.s, p0/m, z0.s, z1.s | |
| ; SVE-NEXT: fcvt h0, s0 | |
| ; SVE-NEXT: ret | |
| ; | |
| ; GISEL-LABEL: test_ldexp_v1f16_v1i32: | |
| ; GISEL: // %bb.0: | |
| ; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; GISEL-NEXT: fcvt s0, h0 | |
| ; GISEL-NEXT: fmov w0, s1 | |
| ; GISEL-NEXT: bl ldexpf | |
| ; GISEL-NEXT: fcvt h0, s0 | |
| ; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; GISEL-NEXT: ret | |
| ; | |
| ; WINDOWS-LABEL: test_ldexp_v1f16_v1i32: | |
| ; WINDOWS: // %bb.0: | |
| ; WINDOWS-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |
| ; WINDOWS-NEXT: fcvt d0, h0 | |
| ; WINDOWS-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; WINDOWS-NEXT: fmov w0, s1 | |
| ; WINDOWS-NEXT: bl ldexp | |
| ; WINDOWS-NEXT: fcvt h0, d0 | |
| ; WINDOWS-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |
| ; WINDOWS-NEXT: ret | |
| %result = call <1 x half> @llvm.ldexp.v1f16.v1i32(<1 x half> %val, <1 x i32> %exp) | |
| ret <1 x half> %result | |
| } |