323 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 vfnmacc and vfnmadd by using different operand orders to8; trigger commuting in TwoAddressInstructionPass.9 10define <2 x half> @vfnmsub_vv_v2f16(<2 x half> %va, <2 x half> %vb, <2 x half> %vc) strictfp {11; CHECK-LABEL: vfnmsub_vv_v2f16:12; CHECK: # %bb.0:13; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma14; CHECK-NEXT: vfnmadd.vv v8, v10, v915; CHECK-NEXT: ret16 %neg = fneg <2 x half> %va17 %neg2 = fneg <2 x half> %vb18 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %neg, <2 x half> %vc, <2 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")19 ret <2 x half> %vd20}21 22define <2 x half> @vfnmsub_vf_v2f16(<2 x half> %va, <2 x half> %vb, half %c) strictfp {23; CHECK-LABEL: vfnmsub_vf_v2f16:24; CHECK: # %bb.0:25; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma26; CHECK-NEXT: vfnmadd.vf v8, fa0, v927; CHECK-NEXT: ret28 %head = insertelement <2 x half> poison, half %c, i32 029 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer30 %neg = fneg <2 x half> %va31 %neg2 = fneg <2 x half> %vb32 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %splat, <2 x half> %neg, <2 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")33 ret <2 x half> %vd34}35 36define <4 x half> @vfnmsub_vv_v4f16(<4 x half> %va, <4 x half> %vb, <4 x half> %vc) strictfp {37; CHECK-LABEL: vfnmsub_vv_v4f16:38; CHECK: # %bb.0:39; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma40; CHECK-NEXT: vfnmadd.vv v8, v9, v1041; CHECK-NEXT: ret42 %neg = fneg <4 x half> %vb43 %neg2 = fneg <4 x half> %vc44 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %neg, <4 x half> %va, <4 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")45 ret <4 x half> %vd46}47 48define <4 x half> @vfnmsub_vf_v4f16(<4 x half> %va, <4 x half> %vb, half %c) strictfp {49; CHECK-LABEL: vfnmsub_vf_v4f16:50; CHECK: # %bb.0:51; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma52; CHECK-NEXT: vfnmadd.vf v8, fa0, v953; CHECK-NEXT: ret54 %head = insertelement <4 x half> poison, half %c, i32 055 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer56 %neg = fneg <4 x half> %splat57 %neg2 = fneg <4 x half> %vb58 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %va, <4 x half> %neg, <4 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")59 ret <4 x half> %vd60}61 62define <8 x half> @vfnmsub_vv_v8f16(<8 x half> %va, <8 x half> %vb, <8 x half> %vc) strictfp {63; CHECK-LABEL: vfnmsub_vv_v8f16:64; CHECK: # %bb.0:65; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma66; CHECK-NEXT: vfnmacc.vv v8, v10, v967; CHECK-NEXT: ret68 %neg = fneg <8 x half> %vb69 %neg2 = fneg <8 x half> %va70 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %neg, <8 x half> %vc, <8 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")71 ret <8 x half> %vd72}73 74define <8 x half> @vfnmsub_vf_v8f16(<8 x half> %va, <8 x half> %vb, half %c) strictfp {75; CHECK-LABEL: vfnmsub_vf_v8f16:76; CHECK: # %bb.0:77; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma78; CHECK-NEXT: vfnmacc.vf v8, fa0, v979; CHECK-NEXT: ret80 %head = insertelement <8 x half> poison, half %c, i32 081 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer82 %neg = fneg <8 x half> %splat83 %neg2 = fneg <8 x half> %va84 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %neg, <8 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")85 ret <8 x half> %vd86}87 88define <16 x half> @vfnmsub_vv_v16f16(<16 x half> %va, <16 x half> %vb, <16 x half> %vc) strictfp {89; CHECK-LABEL: vfnmsub_vv_v16f16:90; CHECK: # %bb.0:91; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma92; CHECK-NEXT: vfnmadd.vv v8, v12, v1093; CHECK-NEXT: ret94 %neg = fneg <16 x half> %vc95 %neg2 = fneg <16 x half> %vb96 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %neg, <16 x half> %va, <16 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")97 ret <16 x half> %vd98}99 100define <16 x half> @vfnmsub_vf_v16f16(<16 x half> %va, <16 x half> %vb, half %c) strictfp {101; CHECK-LABEL: vfnmsub_vf_v16f16:102; CHECK: # %bb.0:103; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma104; CHECK-NEXT: vfnmadd.vf v8, fa0, v10105; CHECK-NEXT: ret106 %head = insertelement <16 x half> poison, half %c, i32 0107 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer108 %neg = fneg <16 x half> %splat109 %neg2 = fneg <16 x half> %vb110 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %neg, <16 x half> %va, <16 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")111 ret <16 x half> %vd112}113 114define <32 x half> @vfnmsub_vv_v32f16(<32 x half> %va, <32 x half> %vb, <32 x half> %vc) strictfp {115; CHECK-LABEL: vfnmsub_vv_v32f16:116; CHECK: # %bb.0:117; CHECK-NEXT: li a0, 32118; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma119; CHECK-NEXT: vfnmadd.vv v8, v16, v12120; CHECK-NEXT: ret121 %neg = fneg <32 x half> %vc122 %neg2 = fneg <32 x half> %vb123 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %neg, <32 x half> %va, <32 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")124 ret <32 x half> %vd125}126 127define <32 x half> @vfnmsub_vf_v32f16(<32 x half> %va, <32 x half> %vb, half %c) strictfp {128; CHECK-LABEL: vfnmsub_vf_v32f16:129; CHECK: # %bb.0:130; CHECK-NEXT: li a0, 32131; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma132; CHECK-NEXT: vfnmacc.vf v8, fa0, v12133; CHECK-NEXT: ret134 %head = insertelement <32 x half> poison, half %c, i32 0135 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer136 %neg = fneg <32 x half> %splat137 %neg2 = fneg <32 x half> %va138 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %neg, <32 x half> %vb, <32 x half> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")139 ret <32 x half> %vd140}141 142define <2 x float> @vfnmsub_vv_v2f32(<2 x float> %va, <2 x float> %vb, <2 x float> %vc) strictfp {143; CHECK-LABEL: vfnmsub_vv_v2f32:144; CHECK: # %bb.0:145; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma146; CHECK-NEXT: vfnmadd.vv v8, v10, v9147; CHECK-NEXT: ret148 %neg = fneg <2 x float> %vc149 %neg2 = fneg <2 x float> %vb150 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %va, <2 x float> %neg, <2 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")151 ret <2 x float> %vd152}153 154define <2 x float> @vfnmsub_vf_v2f32(<2 x float> %va, <2 x float> %vb, float %c) strictfp {155; CHECK-LABEL: vfnmsub_vf_v2f32:156; CHECK: # %bb.0:157; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma158; CHECK-NEXT: vfnmadd.vf v8, fa0, v9159; CHECK-NEXT: ret160 %head = insertelement <2 x float> poison, float %c, i32 0161 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer162 %neg = fneg <2 x float> %va163 %neg2 = fneg <2 x float> %vb164 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %splat, <2 x float> %neg, <2 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")165 ret <2 x float> %vd166}167 168define <4 x float> @vfnmsub_vv_v4f32(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) strictfp {169; CHECK-LABEL: vfnmsub_vv_v4f32:170; CHECK: # %bb.0:171; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma172; CHECK-NEXT: vfnmadd.vv v8, v9, v10173; CHECK-NEXT: ret174 %neg = fneg <4 x float> %va175 %neg2 = fneg <4 x float> %vc176 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %vb, <4 x float> %neg, <4 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")177 ret <4 x float> %vd178}179 180define <4 x float> @vfnmsub_vf_v4f32(<4 x float> %va, <4 x float> %vb, float %c) strictfp {181; CHECK-LABEL: vfnmsub_vf_v4f32:182; CHECK: # %bb.0:183; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma184; CHECK-NEXT: vfnmadd.vf v8, fa0, v9185; CHECK-NEXT: ret186 %head = insertelement <4 x float> poison, float %c, i32 0187 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer188 %neg = fneg <4 x float> %splat189 %neg2 = fneg <4 x float> %vb190 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %va, <4 x float> %neg, <4 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")191 ret <4 x float> %vd192}193 194define <8 x float> @vfnmsub_vv_v8f32(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) strictfp {195; CHECK-LABEL: vfnmsub_vv_v8f32:196; CHECK: # %bb.0:197; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma198; CHECK-NEXT: vfnmacc.vv v8, v12, v10199; CHECK-NEXT: ret200 %neg = fneg <8 x float> %vc201 %neg2 = fneg <8 x float> %va202 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %neg, <8 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")203 ret <8 x float> %vd204}205 206define <8 x float> @vfnmsub_vf_v8f32(<8 x float> %va, <8 x float> %vb, float %c) strictfp {207; CHECK-LABEL: vfnmsub_vf_v8f32:208; CHECK: # %bb.0:209; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma210; CHECK-NEXT: vfnmacc.vf v8, fa0, v10211; CHECK-NEXT: ret212 %head = insertelement <8 x float> poison, float %c, i32 0213 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer214 %neg = fneg <8 x float> %splat215 %neg2 = fneg <8 x float> %va216 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %neg, <8 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")217 ret <8 x float> %vd218}219 220define <16 x float> @vfnmsub_vv_v16f32(<16 x float> %va, <16 x float> %vb, <16 x float> %vc) strictfp {221; CHECK-LABEL: vfnmsub_vv_v16f32:222; CHECK: # %bb.0:223; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma224; CHECK-NEXT: vfnmadd.vv v8, v16, v12225; CHECK-NEXT: ret226 %neg = fneg <16 x float> %va227 %neg2 = fneg <16 x float> %vb228 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %vc, <16 x float> %neg, <16 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")229 ret <16 x float> %vd230}231 232define <16 x float> @vfnmsub_vf_v16f32(<16 x float> %va, <16 x float> %vb, float %c) strictfp {233; CHECK-LABEL: vfnmsub_vf_v16f32:234; CHECK: # %bb.0:235; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma236; CHECK-NEXT: vfnmadd.vf v8, fa0, v12237; CHECK-NEXT: ret238 %head = insertelement <16 x float> poison, float %c, i32 0239 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer240 %neg = fneg <16 x float> %splat241 %neg2 = fneg <16 x float> %vb242 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %neg, <16 x float> %va, <16 x float> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")243 ret <16 x float> %vd244}245 246define <2 x double> @vfnmsub_vv_v2f64(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) strictfp {247; CHECK-LABEL: vfnmsub_vv_v2f64:248; CHECK: # %bb.0:249; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma250; CHECK-NEXT: vfnmadd.vv v8, v10, v9251; CHECK-NEXT: ret252 %neg = fneg <2 x double> %va253 %neg2 = fneg <2 x double> %vb254 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %neg, <2 x double> %vc, <2 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")255 ret <2 x double> %vd256}257 258define <2 x double> @vfnmsub_vf_v2f64(<2 x double> %va, <2 x double> %vb, double %c) strictfp {259; CHECK-LABEL: vfnmsub_vf_v2f64:260; CHECK: # %bb.0:261; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma262; CHECK-NEXT: vfnmadd.vf v8, fa0, v9263; CHECK-NEXT: ret264 %head = insertelement <2 x double> poison, double %c, i32 0265 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer266 %neg = fneg <2 x double> %va267 %neg2 = fneg <2 x double> %vb268 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %splat, <2 x double> %neg, <2 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")269 ret <2 x double> %vd270}271 272define <4 x double> @vfnmsub_vv_v4f64(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) strictfp {273; CHECK-LABEL: vfnmsub_vv_v4f64:274; CHECK: # %bb.0:275; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma276; CHECK-NEXT: vfnmadd.vv v8, v10, v12277; CHECK-NEXT: ret278 %neg = fneg <4 x double> %vb279 %neg2 = fneg <4 x double> %vc280 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %neg, <4 x double> %va, <4 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")281 ret <4 x double> %vd282}283 284define <4 x double> @vfnmsub_vf_v4f64(<4 x double> %va, <4 x double> %vb, double %c) strictfp {285; CHECK-LABEL: vfnmsub_vf_v4f64:286; CHECK: # %bb.0:287; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma288; CHECK-NEXT: vfnmadd.vf v8, fa0, v10289; CHECK-NEXT: ret290 %head = insertelement <4 x double> poison, double %c, i32 0291 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer292 %neg = fneg <4 x double> %splat293 %neg2 = fneg <4 x double> %vb294 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %va, <4 x double> %neg, <4 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")295 ret <4 x double> %vd296}297 298define <8 x double> @vfnmsub_vv_v8f64(<8 x double> %va, <8 x double> %vb, <8 x double> %vc) strictfp {299; CHECK-LABEL: vfnmsub_vv_v8f64:300; CHECK: # %bb.0:301; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma302; CHECK-NEXT: vfnmacc.vv v8, v16, v12303; CHECK-NEXT: ret304 %neg = fneg <8 x double> %vb305 %neg2 = fneg <8 x double> %va306 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %neg, <8 x double> %vc, <8 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")307 ret <8 x double> %vd308}309 310define <8 x double> @vfnmsub_vf_v8f64(<8 x double> %va, <8 x double> %vb, double %c) strictfp {311; CHECK-LABEL: vfnmsub_vf_v8f64:312; CHECK: # %bb.0:313; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma314; CHECK-NEXT: vfnmacc.vf v8, fa0, v12315; CHECK-NEXT: ret316 %head = insertelement <8 x double> poison, double %c, i32 0317 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer318 %neg = fneg <8 x double> %splat319 %neg2 = fneg <8 x double> %va320 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %neg, <8 x double> %neg2, metadata !"round.dynamic", metadata !"fpexcept.strict")321 ret <8 x double> %vd322}323