299 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v -target-abi=ilp32d \3; RUN: -verify-machineinstrs < %s | FileCheck %s4; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v -target-abi=lp64d \5; RUN: -verify-machineinstrs < %s | FileCheck %s6 7; This tests a mix of vfmsac and vfmsub by using different operand orders to8; trigger commuting in TwoAddressInstructionPass.9 10define <2 x half> @vfmsub_vv_v2f16(<2 x half> %va, <2 x half> %vb, <2 x half> %vc) strictfp {11; CHECK-LABEL: vfmsub_vv_v2f16:12; CHECK: # %bb.0:13; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma14; CHECK-NEXT: vfmsub.vv v8, v10, v915; CHECK-NEXT: ret16 %neg = fneg <2 x half> %vb17 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %va, <2 x half> %vc, <2 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")18 ret <2 x half> %vd19}20 21define <2 x half> @vfmsub_vf_v2f16(<2 x half> %va, <2 x half> %vb, half %c) strictfp {22; CHECK-LABEL: vfmsub_vf_v2f16:23; CHECK: # %bb.0:24; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma25; CHECK-NEXT: vfmsac.vf v8, fa0, v926; CHECK-NEXT: ret27 %head = insertelement <2 x half> poison, half %c, i32 028 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer29 %neg = fneg <2 x half> %va30 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %vb, <2 x half> %splat, <2 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")31 ret <2 x half> %vd32}33 34define <4 x half> @vfmsub_vv_v4f16(<4 x half> %va, <4 x half> %vb, <4 x half> %vc) strictfp {35; CHECK-LABEL: vfmsub_vv_v4f16:36; CHECK: # %bb.0:37; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma38; CHECK-NEXT: vfmsub.vv v8, v9, v1039; CHECK-NEXT: ret40 %neg = fneg <4 x half> %vc41 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %vb, <4 x half> %va, <4 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")42 ret <4 x half> %vd43}44 45define <4 x half> @vfmsub_vf_v4f16(<4 x half> %va, <4 x half> %vb, half %c) strictfp {46; CHECK-LABEL: vfmsub_vf_v4f16:47; CHECK: # %bb.0:48; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma49; CHECK-NEXT: vfmsub.vf v8, fa0, v950; CHECK-NEXT: ret51 %head = insertelement <4 x half> poison, half %c, i32 052 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer53 %neg = fneg <4 x half> %vb54 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %va, <4 x half> %splat, <4 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")55 ret <4 x half> %vd56}57 58define <8 x half> @vfmsub_vv_v8f16(<8 x half> %va, <8 x half> %vb, <8 x half> %vc) strictfp {59; CHECK-LABEL: vfmsub_vv_v8f16:60; CHECK: # %bb.0:61; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma62; CHECK-NEXT: vfmsac.vv v8, v10, v963; CHECK-NEXT: ret64 %neg = fneg <8 x half> %va65 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %vc, <8 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")66 ret <8 x half> %vd67}68 69define <8 x half> @vfmsub_vf_v8f16(<8 x half> %va, <8 x half> %vb, half %c) strictfp {70; CHECK-LABEL: vfmsub_vf_v8f16:71; CHECK: # %bb.0:72; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma73; CHECK-NEXT: vfmsac.vf v8, fa0, v974; CHECK-NEXT: ret75 %head = insertelement <8 x half> poison, half %c, i32 076 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer77 %neg = fneg <8 x half> %va78 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %splat, <8 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")79 ret <8 x half> %vd80}81 82define <16 x half> @vfmsub_vv_v16f16(<16 x half> %va, <16 x half> %vb, <16 x half> %vc) strictfp {83; CHECK-LABEL: vfmsub_vv_v16f16:84; CHECK: # %bb.0:85; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma86; CHECK-NEXT: vfmsub.vv v8, v12, v1087; CHECK-NEXT: ret88 %neg = fneg <16 x half> %vb89 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %vc, <16 x half> %va, <16 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")90 ret <16 x half> %vd91}92 93define <16 x half> @vfmsub_vf_v16f16(<16 x half> %va, <16 x half> %vb, half %c) strictfp {94; CHECK-LABEL: vfmsub_vf_v16f16:95; CHECK: # %bb.0:96; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma97; CHECK-NEXT: vfmsub.vf v8, fa0, v1098; CHECK-NEXT: ret99 %head = insertelement <16 x half> poison, half %c, i32 0100 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer101 %neg = fneg <16 x half> %vb102 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %va, <16 x half> %splat, <16 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")103 ret <16 x half> %vd104}105 106define <32 x half> @vfmsub_vv_v32f16(<32 x half> %va, <32 x half> %vb, <32 x half> %vc) strictfp {107; CHECK-LABEL: vfmsub_vv_v32f16:108; CHECK: # %bb.0:109; CHECK-NEXT: li a0, 32110; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma111; CHECK-NEXT: vfmsac.vv v8, v16, v12112; CHECK-NEXT: ret113 %neg = fneg <32 x half> %va114 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vc, <32 x half> %vb, <32 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")115 ret <32 x half> %vd116}117 118define <32 x half> @vfmsub_vf_v32f16(<32 x half> %va, <32 x half> %vb, half %c) strictfp {119; CHECK-LABEL: vfmsub_vf_v32f16:120; CHECK: # %bb.0:121; CHECK-NEXT: li a0, 32122; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma123; CHECK-NEXT: vfmsac.vf v8, fa0, v12124; CHECK-NEXT: ret125 %head = insertelement <32 x half> poison, half %c, i32 0126 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer127 %neg = fneg <32 x half> %va128 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vb, <32 x half> %splat, <32 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")129 ret <32 x half> %vd130}131 132define <2 x float> @vfmsub_vv_v2f32(<2 x float> %va, <2 x float> %vb, <2 x float> %vc) strictfp {133; CHECK-LABEL: vfmsub_vv_v2f32:134; CHECK: # %bb.0:135; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma136; CHECK-NEXT: vfmsub.vv v8, v10, v9137; CHECK-NEXT: ret138 %neg = fneg <2 x float> %vb139 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %va, <2 x float> %vc, <2 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")140 ret <2 x float> %vd141}142 143define <2 x float> @vfmsub_vf_v2f32(<2 x float> %va, <2 x float> %vb, float %c) strictfp {144; CHECK-LABEL: vfmsub_vf_v2f32:145; CHECK: # %bb.0:146; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma147; CHECK-NEXT: vfmsac.vf v8, fa0, v9148; CHECK-NEXT: ret149 %head = insertelement <2 x float> poison, float %c, i32 0150 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer151 %neg = fneg <2 x float> %va152 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %vb, <2 x float> %splat, <2 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")153 ret <2 x float> %vd154}155 156define <4 x float> @vfmsub_vv_v4f32(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) strictfp {157; CHECK-LABEL: vfmsub_vv_v4f32:158; CHECK: # %bb.0:159; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma160; CHECK-NEXT: vfmsub.vv v8, v9, v10161; CHECK-NEXT: ret162 %neg = fneg <4 x float> %vc163 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %vb, <4 x float> %va, <4 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")164 ret <4 x float> %vd165}166 167define <4 x float> @vfmsub_vf_v4f32(<4 x float> %va, <4 x float> %vb, float %c) strictfp {168; CHECK-LABEL: vfmsub_vf_v4f32:169; CHECK: # %bb.0:170; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma171; CHECK-NEXT: vfmsub.vf v8, fa0, v9172; CHECK-NEXT: ret173 %head = insertelement <4 x float> poison, float %c, i32 0174 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer175 %neg = fneg <4 x float> %vb176 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %va, <4 x float> %splat, <4 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")177 ret <4 x float> %vd178}179 180define <8 x float> @vfmsub_vv_v8f32(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) strictfp {181; CHECK-LABEL: vfmsub_vv_v8f32:182; CHECK: # %bb.0:183; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma184; CHECK-NEXT: vfmsac.vv v8, v12, v10185; CHECK-NEXT: ret186 %neg = fneg <8 x float> %va187 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %vc, <8 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")188 ret <8 x float> %vd189}190 191define <8 x float> @vfmsub_vf_v8f32(<8 x float> %va, <8 x float> %vb, float %c) strictfp {192; CHECK-LABEL: vfmsub_vf_v8f32:193; CHECK: # %bb.0:194; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma195; CHECK-NEXT: vfmsac.vf v8, fa0, v10196; CHECK-NEXT: ret197 %head = insertelement <8 x float> poison, float %c, i32 0198 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer199 %neg = fneg <8 x float> %va200 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %splat, <8 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")201 ret <8 x float> %vd202}203 204define <16 x float> @vfmsub_vv_v16f32(<16 x float> %va, <16 x float> %vb, <16 x float> %vc) strictfp {205; CHECK-LABEL: vfmsub_vv_v16f32:206; CHECK: # %bb.0:207; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma208; CHECK-NEXT: vfmsub.vv v8, v16, v12209; CHECK-NEXT: ret210 %neg = fneg <16 x float> %vb211 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %vc, <16 x float> %va, <16 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")212 ret <16 x float> %vd213}214 215define <16 x float> @vfmsub_vf_v16f32(<16 x float> %va, <16 x float> %vb, float %c) strictfp {216; CHECK-LABEL: vfmsub_vf_v16f32:217; CHECK: # %bb.0:218; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma219; CHECK-NEXT: vfmsub.vf v8, fa0, v12220; CHECK-NEXT: ret221 %head = insertelement <16 x float> poison, float %c, i32 0222 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer223 %neg = fneg <16 x float> %vb224 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %va, <16 x float> %splat, <16 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")225 ret <16 x float> %vd226}227 228define <2 x double> @vfmsub_vv_v2f64(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) strictfp {229; CHECK-LABEL: vfmsub_vv_v2f64:230; CHECK: # %bb.0:231; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma232; CHECK-NEXT: vfmsub.vv v8, v10, v9233; CHECK-NEXT: ret234 %neg = fneg <2 x double> %vb235 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %va, <2 x double> %vc, <2 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")236 ret <2 x double> %vd237}238 239define <2 x double> @vfmsub_vf_v2f64(<2 x double> %va, <2 x double> %vb, double %c) strictfp {240; CHECK-LABEL: vfmsub_vf_v2f64:241; CHECK: # %bb.0:242; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma243; CHECK-NEXT: vfmsac.vf v8, fa0, v9244; CHECK-NEXT: ret245 %head = insertelement <2 x double> poison, double %c, i32 0246 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer247 %neg = fneg <2 x double> %va248 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %vb, <2 x double> %splat, <2 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")249 ret <2 x double> %vd250}251 252define <4 x double> @vfmsub_vv_v4f64(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) strictfp {253; CHECK-LABEL: vfmsub_vv_v4f64:254; CHECK: # %bb.0:255; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma256; CHECK-NEXT: vfmsub.vv v8, v10, v12257; CHECK-NEXT: ret258 %neg = fneg <4 x double> %vc259 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %vb, <4 x double> %va, <4 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")260 ret <4 x double> %vd261}262 263define <4 x double> @vfmsub_vf_v4f64(<4 x double> %va, <4 x double> %vb, double %c) strictfp {264; CHECK-LABEL: vfmsub_vf_v4f64:265; CHECK: # %bb.0:266; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma267; CHECK-NEXT: vfmsub.vf v8, fa0, v10268; CHECK-NEXT: ret269 %head = insertelement <4 x double> poison, double %c, i32 0270 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer271 %neg = fneg <4 x double> %vb272 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %va, <4 x double> %splat, <4 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")273 ret <4 x double> %vd274}275 276define <8 x double> @vfmsub_vv_v8f64(<8 x double> %va, <8 x double> %vb, <8 x double> %vc) strictfp {277; CHECK-LABEL: vfmsub_vv_v8f64:278; CHECK: # %bb.0:279; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma280; CHECK-NEXT: vfmsac.vv v8, v16, v12281; CHECK-NEXT: ret282 %neg = fneg <8 x double> %va283 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %vc, <8 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")284 ret <8 x double> %vd285}286 287define <8 x double> @vfmsub_vf_v8f64(<8 x double> %va, <8 x double> %vb, double %c) strictfp {288; CHECK-LABEL: vfmsub_vf_v8f64:289; CHECK: # %bb.0:290; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma291; CHECK-NEXT: vfmsac.vf v8, fa0, v12292; CHECK-NEXT: ret293 %head = insertelement <8 x double> poison, double %c, i32 0294 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer295 %neg = fneg <8 x double> %va296 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %splat, <8 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")297 ret <8 x double> %vd298}299