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