| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-neon-syntax=apple -mattr=+fullfp16 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD |
| ; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-neon-syntax=apple -mattr=+fullfp16 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI |
| |
| ;; ---- sitofp + fdiv (power-of-2 divisors) ---- |
| |
| define <2 x float> @sitofp_v2f32_fdiv_2(<2 x i32> %in) { |
| ; CHECK-SD-LABEL: sitofp_v2f32_fdiv_2: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.2s v0, v0, #1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v2f32_fdiv_2: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.2s v1, #64, lsl #24 |
| ; CHECK-GI-NEXT: scvtf.2s v0, v0 |
| ; CHECK-GI-NEXT: fdiv.2s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <2 x i32> %in to <2 x float> |
| %div = fdiv <2 x float> %conv, <float 2.0, float 2.0> |
| ret <2 x float> %div |
| } |
| |
| define <4 x float> @sitofp_v4f32_fdiv_4(<4 x i32> %in) { |
| ; CHECK-SD-LABEL: sitofp_v4f32_fdiv_4: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.4s v0, v0, #2 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v4f32_fdiv_4: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: fmov.4s v1, #4.00000000 |
| ; CHECK-GI-NEXT: scvtf.4s v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <4 x i32> %in to <4 x float> |
| %div = fdiv <4 x float> %conv, <float 4.0, float 4.0, float 4.0, float 4.0> |
| ret <4 x float> %div |
| } |
| |
| define <2 x double> @sitofp_v2f64_fdiv_16(<2 x i64> %in) { |
| ; CHECK-SD-LABEL: sitofp_v2f64_fdiv_16: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.2d v0, v0, #4 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v2f64_fdiv_16: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: fmov.2d v1, #16.00000000 |
| ; CHECK-GI-NEXT: scvtf.2d v0, v0 |
| ; CHECK-GI-NEXT: fdiv.2d v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <2 x i64> %in to <2 x double> |
| %div = fdiv <2 x double> %conv, <double 16.0, double 16.0> |
| ret <2 x double> %div |
| } |
| |
| define <4 x half> @sitofp_v4f16_fdiv_8(<4 x i16> %in) { |
| ; CHECK-SD-LABEL: sitofp_v4f16_fdiv_8: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.4h v0, v0, #3 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v4f16_fdiv_8: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.4h v1, #72, lsl #8 |
| ; CHECK-GI-NEXT: scvtf.4h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <4 x i16> %in to <4 x half> |
| %div = fdiv <4 x half> %conv, <half 8.0, half 8.0, half 8.0, half 8.0> |
| ret <4 x half> %div |
| } |
| |
| define <8 x half> @sitofp_v8f16_fdiv_4(<8 x i16> %in) { |
| ; CHECK-SD-LABEL: sitofp_v8f16_fdiv_4: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.8h v0, v0, #2 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v8f16_fdiv_4: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.8h v1, #68, lsl #8 |
| ; CHECK-GI-NEXT: scvtf.8h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.8h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <8 x i16> %in to <8 x half> |
| %div = fdiv <8 x half> %conv, <half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0> |
| ret <8 x half> %div |
| } |
| |
| ;; ---- sitofp + fmul (reciprocal power-of-2 multipliers) ---- |
| |
| define <2 x float> @sitofp_v2f32_fmul_half(<2 x i32> %in) { |
| ; CHECK-LABEL: sitofp_v2f32_fmul_half: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: scvtf.2s v0, v0, #1 |
| ; CHECK-NEXT: ret |
| %conv = sitofp <2 x i32> %in to <2 x float> |
| %mul = fmul <2 x float> %conv, <float 0.5, float 0.5> |
| ret <2 x float> %mul |
| } |
| |
| define <4 x float> @sitofp_v4f32_fmul_quarter(<4 x i32> %in) { |
| ; CHECK-LABEL: sitofp_v4f32_fmul_quarter: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: scvtf.4s v0, v0, #2 |
| ; CHECK-NEXT: ret |
| %conv = sitofp <4 x i32> %in to <4 x float> |
| %mul = fmul <4 x float> %conv, <float 0.25, float 0.25, float 0.25, float 0.25> |
| ret <4 x float> %mul |
| } |
| |
| define <2 x double> @sitofp_v2f64_fmul_eighth(<2 x i64> %in) { |
| ; CHECK-LABEL: sitofp_v2f64_fmul_eighth: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: scvtf.2d v0, v0, #3 |
| ; CHECK-NEXT: ret |
| %conv = sitofp <2 x i64> %in to <2 x double> |
| %mul = fmul <2 x double> %conv, <double 0.125, double 0.125> |
| ret <2 x double> %mul |
| } |
| |
| define <4 x half> @sitofp_v4f16_fmul_half(<4 x i16> %in) { |
| ; CHECK-LABEL: sitofp_v4f16_fmul_half: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: scvtf.4h v0, v0, #1 |
| ; CHECK-NEXT: ret |
| %conv = sitofp <4 x i16> %in to <4 x half> |
| %mul = fmul <4 x half> %conv, <half 0xH3800, half 0xH3800, half 0xH3800, half 0xH3800> |
| ret <4 x half> %mul |
| } |
| |
| define <8 x half> @sitofp_v8f16_fmul_quarter(<8 x i16> %in) { |
| ; CHECK-LABEL: sitofp_v8f16_fmul_quarter: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: scvtf.8h v0, v0, #2 |
| ; CHECK-NEXT: ret |
| %conv = sitofp <8 x i16> %in to <8 x half> |
| %mul = fmul <8 x half> %conv, <half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400> |
| ret <8 x half> %mul |
| } |
| |
| ;; ---- uitofp + fdiv (unsigned) ---- |
| |
| define <2 x float> @uitofp_v2f32_fdiv_2(<2 x i32> %in) { |
| ; CHECK-SD-LABEL: uitofp_v2f32_fdiv_2: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: ucvtf.2s v0, v0, #1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: uitofp_v2f32_fdiv_2: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.2s v1, #64, lsl #24 |
| ; CHECK-GI-NEXT: ucvtf.2s v0, v0 |
| ; CHECK-GI-NEXT: fdiv.2s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = uitofp <2 x i32> %in to <2 x float> |
| %div = fdiv <2 x float> %conv, <float 2.0, float 2.0> |
| ret <2 x float> %div |
| } |
| |
| define <4 x float> @uitofp_v4f32_fdiv_4(<4 x i32> %in) { |
| ; CHECK-SD-LABEL: uitofp_v4f32_fdiv_4: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: ucvtf.4s v0, v0, #2 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: uitofp_v4f32_fdiv_4: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: fmov.4s v1, #4.00000000 |
| ; CHECK-GI-NEXT: ucvtf.4s v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = uitofp <4 x i32> %in to <4 x float> |
| %div = fdiv <4 x float> %conv, <float 4.0, float 4.0, float 4.0, float 4.0> |
| ret <4 x float> %div |
| } |
| |
| define <2 x double> @uitofp_v2f64_fdiv_16(<2 x i64> %in) { |
| ; CHECK-SD-LABEL: uitofp_v2f64_fdiv_16: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: ucvtf.2d v0, v0, #4 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: uitofp_v2f64_fdiv_16: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: fmov.2d v1, #16.00000000 |
| ; CHECK-GI-NEXT: ucvtf.2d v0, v0 |
| ; CHECK-GI-NEXT: fdiv.2d v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = uitofp <2 x i64> %in to <2 x double> |
| %div = fdiv <2 x double> %conv, <double 16.0, double 16.0> |
| ret <2 x double> %div |
| } |
| |
| define <4 x half> @uitofp_v4f16_fdiv_8(<4 x i16> %in) { |
| ; CHECK-SD-LABEL: uitofp_v4f16_fdiv_8: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: ucvtf.4h v0, v0, #3 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: uitofp_v4f16_fdiv_8: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.4h v1, #72, lsl #8 |
| ; CHECK-GI-NEXT: ucvtf.4h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = uitofp <4 x i16> %in to <4 x half> |
| %div = fdiv <4 x half> %conv, <half 8.0, half 8.0, half 8.0, half 8.0> |
| ret <4 x half> %div |
| } |
| |
| define <8 x half> @uitofp_v8f16_fdiv_4(<8 x i16> %in) { |
| ; CHECK-SD-LABEL: uitofp_v8f16_fdiv_4: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: ucvtf.8h v0, v0, #2 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: uitofp_v8f16_fdiv_4: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.8h v1, #68, lsl #8 |
| ; CHECK-GI-NEXT: ucvtf.8h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.8h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = uitofp <8 x i16> %in to <8 x half> |
| %div = fdiv <8 x half> %conv, <half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0> |
| ret <8 x half> %div |
| } |
| |
| ;; ---- uitofp + fmul (unsigned, reciprocal) ---- |
| |
| define <2 x float> @uitofp_v2f32_fmul_half(<2 x i32> %in) { |
| ; CHECK-LABEL: uitofp_v2f32_fmul_half: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ucvtf.2s v0, v0, #1 |
| ; CHECK-NEXT: ret |
| %conv = uitofp <2 x i32> %in to <2 x float> |
| %mul = fmul <2 x float> %conv, <float 0.5, float 0.5> |
| ret <2 x float> %mul |
| } |
| |
| define <4 x float> @uitofp_v4f32_fmul_quarter(<4 x i32> %in) { |
| ; CHECK-LABEL: uitofp_v4f32_fmul_quarter: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ucvtf.4s v0, v0, #2 |
| ; CHECK-NEXT: ret |
| %conv = uitofp <4 x i32> %in to <4 x float> |
| %mul = fmul <4 x float> %conv, <float 0.25, float 0.25, float 0.25, float 0.25> |
| ret <4 x float> %mul |
| } |
| |
| define <2 x double> @uitofp_v2f64_fmul_eighth(<2 x i64> %in) { |
| ; CHECK-LABEL: uitofp_v2f64_fmul_eighth: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ucvtf.2d v0, v0, #3 |
| ; CHECK-NEXT: ret |
| %conv = uitofp <2 x i64> %in to <2 x double> |
| %mul = fmul <2 x double> %conv, <double 0.125, double 0.125> |
| ret <2 x double> %mul |
| } |
| |
| define <4 x half> @uitofp_v4f16_fmul_half(<4 x i16> %in) { |
| ; CHECK-LABEL: uitofp_v4f16_fmul_half: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ucvtf.4h v0, v0, #1 |
| ; CHECK-NEXT: ret |
| %conv = uitofp <4 x i16> %in to <4 x half> |
| %mul = fmul <4 x half> %conv, <half 0xH3800, half 0xH3800, half 0xH3800, half 0xH3800> |
| ret <4 x half> %mul |
| } |
| |
| define <8 x half> @uitofp_v8f16_fmul_quarter(<8 x i16> %in) { |
| ; CHECK-LABEL: uitofp_v8f16_fmul_quarter: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ucvtf.8h v0, v0, #2 |
| ; CHECK-NEXT: ret |
| %conv = uitofp <8 x i16> %in to <8 x half> |
| %mul = fmul <8 x half> %conv, <half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400, half 0xH3400> |
| ret <8 x half> %mul |
| } |
| |
| ;; ---- boundary: max valid shift per element type ---- |
| |
| define <2 x float> @sitofp_v2f32_fdiv_max(<2 x i32> %in) { |
| ; CHECK-SD-LABEL: sitofp_v2f32_fdiv_max: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.2s v0, v0, #32 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v2f32_fdiv_max: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.2s v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI20_0 |
| ; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI20_0] |
| ; CHECK-GI-NEXT: fdiv.2s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^32 = 4294967296.0 — max valid shift for i32 |
| %conv = sitofp <2 x i32> %in to <2 x float> |
| %div = fdiv <2 x float> %conv, <float 4294967296.0, float 4294967296.0> |
| ret <2 x float> %div |
| } |
| |
| define <2 x double> @sitofp_v2f64_fdiv_max(<2 x i64> %in) { |
| ; CHECK-SD-LABEL: sitofp_v2f64_fdiv_max: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.2d v0, v0, #64 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v2f64_fdiv_max: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.2d v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI21_0 |
| ; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI21_0] |
| ; CHECK-GI-NEXT: fdiv.2d v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^64 — max valid shift for i64 |
| %conv = sitofp <2 x i64> %in to <2 x double> |
| %div = fdiv <2 x double> %conv, <double 18446744073709551616.0, double 18446744073709551616.0> |
| ret <2 x double> %div |
| } |
| |
| define <4 x half> @sitofp_v4f16_fdiv_max(<4 x i16> %in) { |
| ; CHECK-SD-LABEL: sitofp_v4f16_fdiv_max: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: movi d1, #0000000000000000 |
| ; CHECK-SD-NEXT: scvtf.4h v0, v0 |
| ; CHECK-SD-NEXT: fmul.4h v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v4f16_fdiv_max: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.4h v1, #124, lsl #8 |
| ; CHECK-GI-NEXT: scvtf.4h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^16 = 65536.0 — max valid shift for i16 (but not representable in f16) |
| ; f16 max is 65504, so 65536.0 overflows to inf. This should NOT match. |
| %conv = sitofp <4 x i16> %in to <4 x half> |
| %div = fdiv <4 x half> %conv, <half 0xH7C00, half 0xH7C00, half 0xH7C00, half 0xH7C00> |
| ret <4 x half> %div |
| } |
| |
| define <4 x half> @sitofp_v4f16_fdiv_1024(<4 x i16> %in) { |
| ; CHECK-SD-LABEL: sitofp_v4f16_fdiv_1024: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: scvtf.4h v0, v0, #10 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: sitofp_v4f16_fdiv_1024: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.4h v1, #100, lsl #8 |
| ; CHECK-GI-NEXT: scvtf.4h v0, v0 |
| ; CHECK-GI-NEXT: fdiv.4h v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^10 = 1024.0 — shift=10, near upper end of f16 range |
| %conv = sitofp <4 x i16> %in to <4 x half> |
| %div = fdiv <4 x half> %conv, <half 1024.0, half 1024.0, half 1024.0, half 1024.0> |
| ret <4 x half> %div |
| } |
| |
| ;; ---- negative: out-of-range shift ---- |
| |
| define <2 x float> @neg_sitofp_v2f32_fdiv_too_large(<2 x i32> %in) { |
| ; CHECK-SD-LABEL: neg_sitofp_v2f32_fdiv_too_large: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: movi.2s v1, #47, lsl #24 |
| ; CHECK-SD-NEXT: scvtf.2s v0, v0 |
| ; CHECK-SD-NEXT: fmul.2s v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: neg_sitofp_v2f32_fdiv_too_large: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: movi.2s v1, #80, lsl #24 |
| ; CHECK-GI-NEXT: scvtf.2s v0, v0 |
| ; CHECK-GI-NEXT: fdiv.2s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^33 — exceeds i32 range, should NOT match |
| %conv = sitofp <2 x i32> %in to <2 x float> |
| %div = fdiv <2 x float> %conv, <float 8589934592.0, float 8589934592.0> |
| ret <2 x float> %div |
| } |
| |
| define <2 x double> @neg_sitofp_v2f64_fdiv_too_large(<2 x i64> %in) { |
| ; CHECK-SD-LABEL: neg_sitofp_v2f64_fdiv_too_large: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: mov x8, #4314448443020935168 // =0x3be0000000000000 |
| ; CHECK-SD-NEXT: scvtf.2d v0, v0 |
| ; CHECK-SD-NEXT: dup.2d v1, x8 |
| ; CHECK-SD-NEXT: fmul.2d v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: neg_sitofp_v2f64_fdiv_too_large: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.2d v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI25_0 |
| ; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI25_0] |
| ; CHECK-GI-NEXT: fdiv.2d v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| ; 2^65 — exceeds i64 range, should NOT match |
| %conv = sitofp <2 x i64> %in to <2 x double> |
| %div = fdiv <2 x double> %conv, <double 36893488147419103232.0, double 36893488147419103232.0> |
| ret <2 x double> %div |
| } |
| |
| ;; ---- negative: non-power-of-2 ---- |
| |
| define <2 x float> @neg_v2f32_fmul_non_pow2(<2 x i32> %in) { |
| ; CHECK-SD-LABEL: neg_v2f32_fmul_non_pow2: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: mov w8, #36704 // =0x8f60 |
| ; CHECK-SD-NEXT: scvtf.2s v0, v0 |
| ; CHECK-SD-NEXT: movk w8, #9666, lsl #16 |
| ; CHECK-SD-NEXT: dup.2s v1, w8 |
| ; CHECK-SD-NEXT: fmul.2s v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: neg_v2f32_fmul_non_pow2: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.2s v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI26_0 |
| ; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI26_0] |
| ; CHECK-GI-NEXT: fmul.2s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <2 x i32> %in to <2 x float> |
| %mul = fmul <2 x float> %conv, <float 0x3CB851EC00000000, float 0x3CB851EC00000000> |
| ret <2 x float> %mul |
| } |
| |
| define <4 x float> @neg_v4f32_fmul_non_pow2(<4 x i32> %in) { |
| ; CHECK-SD-LABEL: neg_v4f32_fmul_non_pow2: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: mov w8, #36704 // =0x8f60 |
| ; CHECK-SD-NEXT: scvtf.4s v0, v0 |
| ; CHECK-SD-NEXT: movk w8, #9666, lsl #16 |
| ; CHECK-SD-NEXT: dup.4s v1, w8 |
| ; CHECK-SD-NEXT: fmul.4s v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: neg_v4f32_fmul_non_pow2: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.4s v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI27_0 |
| ; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI27_0] |
| ; CHECK-GI-NEXT: fmul.4s v0, v0, v1 |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <4 x i32> %in to <4 x float> |
| %mul = fmul <4 x float> %conv, <float 0x3CB851EC00000000, float 0x3CB851EC00000000, float 0x3CB851EC00000000, float 0x3CB851EC00000000> |
| ret <4 x float> %mul |
| } |
| |
| define <2 x double> @neg_v2f64_fmul_non_pow2(<2 x i64> %in) { |
| ; CHECK-SD-LABEL: neg_v2f64_fmul_non_pow2: |
| ; CHECK-SD: // %bb.0: |
| ; CHECK-SD-NEXT: mov x8, #5243 // =0x147b |
| ; CHECK-SD-NEXT: scvtf.2d v0, v0 |
| ; CHECK-SD-NEXT: movk x8, #18350, lsl #16 |
| ; CHECK-SD-NEXT: movk x8, #31457, lsl #32 |
| ; CHECK-SD-NEXT: movk x8, #16276, lsl #48 |
| ; CHECK-SD-NEXT: dup.2d v1, x8 |
| ; CHECK-SD-NEXT: fmul.2d v0, v0, v1 |
| ; CHECK-SD-NEXT: ret |
| ; |
| ; CHECK-GI-LABEL: neg_v2f64_fmul_non_pow2: |
| ; CHECK-GI: // %bb.0: |
| ; CHECK-GI-NEXT: scvtf.2d v0, v0 |
| ; CHECK-GI-NEXT: adrp x8, .LCPI28_0 |
| ; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI28_0] |
| ; CHECK-GI-NEXT: fmul.2d v0, v0, v1[0] |
| ; CHECK-GI-NEXT: ret |
| %conv = sitofp <2 x i64> %in to <2 x double> |
| %mul = fmul <2 x double> %conv, <double 0.02, double 0.02> |
| ret <2 x double> %mul |
| } |