1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+d,+zvfh,+v -target-abi=ilp32d \ 3; RUN: -verify-machineinstrs < %s | FileCheck %s 4; RUN: llc -mtriple=riscv64 -mattr=+d,+zvfh,+v -target-abi=lp64d \ 5; RUN: -verify-machineinstrs < %s | FileCheck %s 6 7; This tests a mix of vfmacc and vfmadd by using different operand orders to 8; trigger commuting in TwoAddressInstructionPass. 9 10declare <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half>, <2 x half>, <2 x half>, metadata, metadata) 11 12define <2 x half> @vfmadd_vv_v2f16(<2 x half> %va, <2 x half> %vb, <2 x half> %vc) strictfp { 13; CHECK-LABEL: vfmadd_vv_v2f16: 14; CHECK: # %bb.0: 15; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma 16; CHECK-NEXT: vfmadd.vv v8, v10, v9 17; CHECK-NEXT: ret 18 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %va, <2 x half> %vc, <2 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 19 ret <2 x half> %vd 20} 21 22define <2 x half> @vfmadd_vf_v2f16(<2 x half> %va, <2 x half> %vb, half %c) strictfp { 23; CHECK-LABEL: vfmadd_vf_v2f16: 24; CHECK: # %bb.0: 25; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma 26; CHECK-NEXT: vfmacc.vf v8, fa0, v9 27; CHECK-NEXT: ret 28 %head = insertelement <2 x half> poison, half %c, i32 0 29 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer 30 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %vb, <2 x half> %splat, <2 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 31 ret <2 x half> %vd 32} 33 34declare <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half>, <4 x half>, <4 x half>, metadata, metadata) 35 36define <4 x half> @vfmadd_vv_v4f16(<4 x half> %va, <4 x half> %vb, <4 x half> %vc) strictfp { 37; CHECK-LABEL: vfmadd_vv_v4f16: 38; CHECK: # %bb.0: 39; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma 40; CHECK-NEXT: vfmadd.vv v8, v9, v10 41; CHECK-NEXT: ret 42 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %vb, <4 x half> %va, <4 x half> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict") 43 ret <4 x half> %vd 44} 45 46define <4 x half> @vfmadd_vf_v4f16(<4 x half> %va, <4 x half> %vb, half %c) strictfp { 47; CHECK-LABEL: vfmadd_vf_v4f16: 48; CHECK: # %bb.0: 49; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma 50; CHECK-NEXT: vfmadd.vf v8, fa0, v9 51; CHECK-NEXT: ret 52 %head = insertelement <4 x half> poison, half %c, i32 0 53 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer 54 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %va, <4 x half> %splat, <4 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 55 ret <4 x half> %vd 56} 57 58declare <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half>, <8 x half>, <8 x half>, metadata, metadata) 59 60define <8 x half> @vfmadd_vv_v8f16(<8 x half> %va, <8 x half> %vb, <8 x half> %vc) strictfp { 61; CHECK-LABEL: vfmadd_vv_v8f16: 62; CHECK: # %bb.0: 63; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma 64; CHECK-NEXT: vfmacc.vv v8, v10, v9 65; CHECK-NEXT: ret 66 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %vc, <8 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 67 ret <8 x half> %vd 68} 69 70define <8 x half> @vfmadd_vf_v8f16(<8 x half> %va, <8 x half> %vb, half %c) strictfp { 71; CHECK-LABEL: vfmadd_vf_v8f16: 72; CHECK: # %bb.0: 73; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma 74; CHECK-NEXT: vfmacc.vf v8, fa0, v9 75; CHECK-NEXT: ret 76 %head = insertelement <8 x half> poison, half %c, i32 0 77 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer 78 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %splat, <8 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 79 ret <8 x half> %vd 80} 81 82declare <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half>, <16 x half>, <16 x half>, metadata, metadata) 83 84define <16 x half> @vfmadd_vv_v16f16(<16 x half> %va, <16 x half> %vb, <16 x half> %vc) strictfp { 85; CHECK-LABEL: vfmadd_vv_v16f16: 86; CHECK: # %bb.0: 87; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma 88; CHECK-NEXT: vfmadd.vv v8, v12, v10 89; CHECK-NEXT: ret 90 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %vc, <16 x half> %va, <16 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 91 ret <16 x half> %vd 92} 93 94define <16 x half> @vfmadd_vf_v16f16(<16 x half> %va, <16 x half> %vb, half %c) strictfp { 95; CHECK-LABEL: vfmadd_vf_v16f16: 96; CHECK: # %bb.0: 97; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma 98; CHECK-NEXT: vfmadd.vf v8, fa0, v10 99; CHECK-NEXT: ret 100 %head = insertelement <16 x half> poison, half %c, i32 0 101 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer 102 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %va, <16 x half> %splat, <16 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 103 ret <16 x half> %vd 104} 105 106declare <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half>, <32 x half>, <32 x half>, metadata, metadata) 107 108define <32 x half> @vfmadd_vv_v32f16(<32 x half> %va, <32 x half> %vb, <32 x half> %vc) strictfp { 109; CHECK-LABEL: vfmadd_vv_v32f16: 110; CHECK: # %bb.0: 111; CHECK-NEXT: li a0, 32 112; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma 113; CHECK-NEXT: vfmacc.vv v8, v16, v12 114; CHECK-NEXT: ret 115 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vc, <32 x half> %vb, <32 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 116 ret <32 x half> %vd 117} 118 119define <32 x half> @vfmadd_vf_v32f16(<32 x half> %va, <32 x half> %vb, half %c) strictfp { 120; CHECK-LABEL: vfmadd_vf_v32f16: 121; CHECK: # %bb.0: 122; CHECK-NEXT: li a0, 32 123; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma 124; CHECK-NEXT: vfmacc.vf v8, fa0, v12 125; CHECK-NEXT: ret 126 %head = insertelement <32 x half> poison, half %c, i32 0 127 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer 128 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vb, <32 x half> %splat, <32 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 129 ret <32 x half> %vd 130} 131 132declare <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float>, <2 x float>, <2 x float>, metadata, metadata) 133 134define <2 x float> @vfmadd_vv_v2f32(<2 x float> %va, <2 x float> %vb, <2 x float> %vc) strictfp { 135; CHECK-LABEL: vfmadd_vv_v2f32: 136; CHECK: # %bb.0: 137; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma 138; CHECK-NEXT: vfmadd.vv v8, v10, v9 139; CHECK-NEXT: ret 140 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %va, <2 x float> %vc, <2 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 141 ret <2 x float> %vd 142} 143 144define <2 x float> @vfmadd_vf_v2f32(<2 x float> %va, <2 x float> %vb, float %c) strictfp { 145; CHECK-LABEL: vfmadd_vf_v2f32: 146; CHECK: # %bb.0: 147; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma 148; CHECK-NEXT: vfmacc.vf v8, fa0, v9 149; CHECK-NEXT: ret 150 %head = insertelement <2 x float> poison, float %c, i32 0 151 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer 152 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %vb, <2 x float> %splat, <2 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 153 ret <2 x float> %vd 154} 155 156declare <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float>, <4 x float>, <4 x float>, metadata, metadata) 157 158define <4 x float> @vfmadd_vv_v4f32(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) strictfp { 159; CHECK-LABEL: vfmadd_vv_v4f32: 160; CHECK: # %bb.0: 161; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 162; CHECK-NEXT: vfmadd.vv v8, v9, v10 163; CHECK-NEXT: ret 164 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %vb, <4 x float> %va, <4 x float> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict") 165 ret <4 x float> %vd 166} 167 168define <4 x float> @vfmadd_vf_v4f32(<4 x float> %va, <4 x float> %vb, float %c) strictfp { 169; CHECK-LABEL: vfmadd_vf_v4f32: 170; CHECK: # %bb.0: 171; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 172; CHECK-NEXT: vfmadd.vf v8, fa0, v9 173; CHECK-NEXT: ret 174 %head = insertelement <4 x float> poison, float %c, i32 0 175 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer 176 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %va, <4 x float> %splat, <4 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 177 ret <4 x float> %vd 178} 179 180declare <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float>, <8 x float>, <8 x float>, metadata, metadata) 181 182define <8 x float> @vfmadd_vv_v8f32(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) strictfp { 183; CHECK-LABEL: vfmadd_vv_v8f32: 184; CHECK: # %bb.0: 185; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma 186; CHECK-NEXT: vfmacc.vv v8, v12, v10 187; CHECK-NEXT: ret 188 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %vc, <8 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 189 ret <8 x float> %vd 190} 191 192define <8 x float> @vfmadd_vf_v8f32(<8 x float> %va, <8 x float> %vb, float %c) strictfp { 193; CHECK-LABEL: vfmadd_vf_v8f32: 194; CHECK: # %bb.0: 195; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma 196; CHECK-NEXT: vfmacc.vf v8, fa0, v10 197; CHECK-NEXT: ret 198 %head = insertelement <8 x float> poison, float %c, i32 0 199 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer 200 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %splat, <8 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 201 ret <8 x float> %vd 202} 203 204declare <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float>, <16 x float>, <16 x float>, metadata, metadata) 205 206define <16 x float> @vfmadd_vv_v16f32(<16 x float> %va, <16 x float> %vb, <16 x float> %vc) strictfp { 207; CHECK-LABEL: vfmadd_vv_v16f32: 208; CHECK: # %bb.0: 209; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma 210; CHECK-NEXT: vfmadd.vv v8, v16, v12 211; CHECK-NEXT: ret 212 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %vc, <16 x float> %va, <16 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 213 ret <16 x float> %vd 214} 215 216define <16 x float> @vfmadd_vf_v16f32(<16 x float> %va, <16 x float> %vb, float %c) strictfp { 217; CHECK-LABEL: vfmadd_vf_v16f32: 218; CHECK: # %bb.0: 219; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma 220; CHECK-NEXT: vfmadd.vf v8, fa0, v12 221; CHECK-NEXT: ret 222 %head = insertelement <16 x float> poison, float %c, i32 0 223 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer 224 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %va, <16 x float> %splat, <16 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 225 ret <16 x float> %vd 226} 227 228declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata) 229 230define <2 x double> @vfmadd_vv_v2f64(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) strictfp { 231; CHECK-LABEL: vfmadd_vv_v2f64: 232; CHECK: # %bb.0: 233; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma 234; CHECK-NEXT: vfmadd.vv v8, v10, v9 235; CHECK-NEXT: ret 236 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %va, <2 x double> %vc, <2 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 237 ret <2 x double> %vd 238} 239 240define <2 x double> @vfmadd_vf_v2f64(<2 x double> %va, <2 x double> %vb, double %c) strictfp { 241; CHECK-LABEL: vfmadd_vf_v2f64: 242; CHECK: # %bb.0: 243; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma 244; CHECK-NEXT: vfmacc.vf v8, fa0, v9 245; CHECK-NEXT: ret 246 %head = insertelement <2 x double> poison, double %c, i32 0 247 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer 248 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %vb, <2 x double> %splat, <2 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 249 ret <2 x double> %vd 250} 251 252declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata) 253 254define <4 x double> @vfmadd_vv_v4f64(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) strictfp { 255; CHECK-LABEL: vfmadd_vv_v4f64: 256; CHECK: # %bb.0: 257; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma 258; CHECK-NEXT: vfmadd.vv v8, v10, v12 259; CHECK-NEXT: ret 260 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %vb, <4 x double> %va, <4 x double> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict") 261 ret <4 x double> %vd 262} 263 264define <4 x double> @vfmadd_vf_v4f64(<4 x double> %va, <4 x double> %vb, double %c) strictfp { 265; CHECK-LABEL: vfmadd_vf_v4f64: 266; CHECK: # %bb.0: 267; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma 268; CHECK-NEXT: vfmadd.vf v8, fa0, v10 269; CHECK-NEXT: ret 270 %head = insertelement <4 x double> poison, double %c, i32 0 271 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer 272 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %va, <4 x double> %splat, <4 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict") 273 ret <4 x double> %vd 274} 275 276declare <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double>, <8 x double>, <8 x double>, metadata, metadata) 277 278define <8 x double> @vfmadd_vv_v8f64(<8 x double> %va, <8 x double> %vb, <8 x double> %vc) strictfp { 279; CHECK-LABEL: vfmadd_vv_v8f64: 280; CHECK: # %bb.0: 281; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma 282; CHECK-NEXT: vfmacc.vv v8, v16, v12 283; CHECK-NEXT: ret 284 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %vc, <8 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 285 ret <8 x double> %vd 286} 287 288define <8 x double> @vfmadd_vf_v8f64(<8 x double> %va, <8 x double> %vb, double %c) strictfp { 289; CHECK-LABEL: vfmadd_vf_v8f64: 290; CHECK: # %bb.0: 291; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma 292; CHECK-NEXT: vfmacc.vf v8, fa0, v12 293; CHECK-NEXT: ret 294 %head = insertelement <8 x double> poison, double %c, i32 0 295 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer 296 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %splat, <8 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict") 297 ret <8 x double> %vd 298} 299