; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-none-linux-gnu -mattr=+neon -fp-contract=fast | FileCheck %s define float @test_fmul_lane_ss2S_0(float %a, <2 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss2S_0: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: fmul s0, s0, s1 ; CHECK-NEXT: ret %tmp1 = extractelement <2 x float> %v, i32 0 %tmp2 = fmul float %a, %tmp1 ret float %tmp2 } define float @test_fmul_lane_ss2S_1(float %a, <2 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss2S_1: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: fmul s0, s0, v1.s[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x float> %v, i32 1 %tmp2 = fmul float %a, %tmp1; ret float %tmp2; } define float @test_fmul_lane_ss2S_1_swap(float %a, <2 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss2S_1_swap: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: fmul s0, s0, v1.s[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x float> %v, i32 1 %tmp2 = fmul float %tmp1, %a; ret float %tmp2; } define float @test_fmul_lane_ss4S_0(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss4S_0: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul s0, s0, s1 ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 0 %tmp2 = fmul float %a, %tmp1 ret float %tmp2 } define float @test_fmul_lane_ss4S_3(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss4S_3: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul s0, s0, v1.s[3] ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 3 %tmp2 = fmul float %a, %tmp1; ret float %tmp2; } define float @test_fmul_lane_ss4S_3_swap(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmul_lane_ss4S_3_swap: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul s0, s0, v1.s[3] ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 3 %tmp2 = fmul float %tmp1, %a; ret float %tmp2; } define double @test_fmul_lane_ddD(double %a, <1 x double> %v) { ; CHECK-LABEL: test_fmul_lane_ddD: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul d0, d0, d1 ; CHECK-NEXT: ret %tmp1 = extractelement <1 x double> %v, i32 0 %tmp2 = fmul double %a, %tmp1; ret double %tmp2; } define double @test_fmul_lane_dd2D_0(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmul_lane_dd2D_0: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul d0, d0, d1 ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 0 %tmp2 = fmul double %a, %tmp1 ret double %tmp2 } define double @test_fmul_lane_dd2D_1(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmul_lane_dd2D_1: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul d0, d0, v1.d[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 1 %tmp2 = fmul double %a, %tmp1; ret double %tmp2; } define double @test_fmul_lane_dd2D_1_swap(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmul_lane_dd2D_1_swap: ; CHECK: // %bb.0: ; CHECK-NEXT: fmul d0, d0, v1.d[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 1 %tmp2 = fmul double %tmp1, %a; ret double %tmp2; } declare float @llvm.aarch64.neon.fmulx.f32(float, float) define float @test_fmulx_lane_f32_0(float %a, <2 x float> %v) { ; CHECK-LABEL: test_fmulx_lane_f32_0: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: fmulx s0, s0, s1 ; CHECK-NEXT: ret %tmp1 = extractelement <2 x float> %v, i32 0 %tmp2 = call float @llvm.aarch64.neon.fmulx.f32(float %a, float %tmp1) ret float %tmp2; } define float @test_fmulx_lane_f32_1(float %a, <2 x float> %v) { ; CHECK-LABEL: test_fmulx_lane_f32_1: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1 ; CHECK-NEXT: fmulx s0, s0, v1.s[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x float> %v, i32 1 %tmp2 = call float @llvm.aarch64.neon.fmulx.f32(float %a, float %tmp1) ret float %tmp2; } define float @test_fmulx_laneq_f32_0(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmulx_laneq_f32_0: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx s0, s0, s1 ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 0 %tmp2 = call float @llvm.aarch64.neon.fmulx.f32(float %a, float %tmp1) ret float %tmp2; } define float @test_fmulx_laneq_f32_3(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmulx_laneq_f32_3: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx s0, s0, v1.s[3] ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 3 %tmp2 = call float @llvm.aarch64.neon.fmulx.f32(float %a, float %tmp1) ret float %tmp2; } define float @test_fmulx_laneq_f32_3_swap(float %a, <4 x float> %v) { ; CHECK-LABEL: test_fmulx_laneq_f32_3_swap: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx s0, s0, v1.s[3] ; CHECK-NEXT: ret %tmp1 = extractelement <4 x float> %v, i32 3 %tmp2 = call float @llvm.aarch64.neon.fmulx.f32(float %tmp1, float %a) ret float %tmp2; } declare double @llvm.aarch64.neon.fmulx.f64(double, double) define double @test_fmulx_lane_f64(double %a, <1 x double> %v) { ; CHECK-LABEL: test_fmulx_lane_f64: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx d0, d0, d1 ; CHECK-NEXT: ret %tmp1 = extractelement <1 x double> %v, i32 0 %tmp2 = call double @llvm.aarch64.neon.fmulx.f64(double %a, double %tmp1) ret double %tmp2; } define double @test_fmulx_laneq_f64_0(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmulx_laneq_f64_0: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx d0, d0, d1 ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 0 %tmp2 = call double @llvm.aarch64.neon.fmulx.f64(double %a, double %tmp1) ret double %tmp2; } define double @test_fmulx_laneq_f64_1(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmulx_laneq_f64_1: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx d0, d0, v1.d[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 1 %tmp2 = call double @llvm.aarch64.neon.fmulx.f64(double %a, double %tmp1) ret double %tmp2; } define double @test_fmulx_laneq_f64_1_swap(double %a, <2 x double> %v) { ; CHECK-LABEL: test_fmulx_laneq_f64_1_swap: ; CHECK: // %bb.0: ; CHECK-NEXT: fmulx d0, d0, v1.d[1] ; CHECK-NEXT: ret %tmp1 = extractelement <2 x double> %v, i32 1 %tmp2 = call double @llvm.aarch64.neon.fmulx.f64(double %tmp1, double %a) ret double %tmp2; } define float @test_fmulx_horizontal_f32(<2 x float> %v) { ; CHECK-LABEL: test_fmulx_horizontal_f32: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 ; CHECK-NEXT: fmulx s0, s0, v0.s[1] ; CHECK-NEXT: ret entry: %0 = extractelement <2 x float> %v, i32 0 %1 = extractelement <2 x float> %v, i32 1 %2 = call float @llvm.aarch64.neon.fmulx.f32(float %0, float %1) ret float %2 } define double @test_fmulx_horizontal_f64(<2 x double> %v) { ; CHECK-LABEL: test_fmulx_horizontal_f64: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fmulx d0, d0, v0.d[1] ; CHECK-NEXT: ret entry: %0 = extractelement <2 x double> %v, i32 0 %1 = extractelement <2 x double> %v, i32 1 %2 = call double @llvm.aarch64.neon.fmulx.f64(double %0, double %1) ret double %2 }