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 7declare <2 x half> @llvm.experimental.constrained.fsub.v2f16(<2 x half>, <2 x half>, metadata, metadata) 8define <2 x half> @vfsub_vv_v2f16(<2 x half> %va, <2 x half> %vb) strictfp { 9; CHECK-LABEL: vfsub_vv_v2f16: 10; CHECK: # %bb.0: # %entry 11; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma 12; CHECK-NEXT: vfsub.vv v8, v8, v9 13; CHECK-NEXT: ret 14entry: 15 %vc = call <2 x half> @llvm.experimental.constrained.fsub.v2f16(<2 x half> %va, <2 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 16 ret <2 x half> %vc 17} 18 19define <2 x half> @vfsub_vf_v2f16(<2 x half> %va, half %b) strictfp { 20; CHECK-LABEL: vfsub_vf_v2f16: 21; CHECK: # %bb.0: 22; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma 23; CHECK-NEXT: vfsub.vf v8, v8, fa0 24; CHECK-NEXT: ret 25 %head = insertelement <2 x half> poison, half %b, i32 0 26 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer 27 %vc = call <2 x half> @llvm.experimental.constrained.fsub.v2f16(<2 x half> %va, <2 x half> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 28 ret <2 x half> %vc 29} 30 31declare <4 x half> @llvm.experimental.constrained.fsub.v4f16(<4 x half>, <4 x half>, metadata, metadata) 32define <4 x half> @vfsub_vv_v4f16(<4 x half> %va, <4 x half> %vb) strictfp { 33; CHECK-LABEL: vfsub_vv_v4f16: 34; CHECK: # %bb.0: # %entry 35; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma 36; CHECK-NEXT: vfsub.vv v8, v8, v9 37; CHECK-NEXT: ret 38entry: 39 %vc = call <4 x half> @llvm.experimental.constrained.fsub.v4f16(<4 x half> %va, <4 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 40 ret <4 x half> %vc 41} 42 43define <4 x half> @vfsub_vf_v4f16(<4 x half> %va, half %b) strictfp { 44; CHECK-LABEL: vfsub_vf_v4f16: 45; CHECK: # %bb.0: 46; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma 47; CHECK-NEXT: vfsub.vf v8, v8, fa0 48; CHECK-NEXT: ret 49 %head = insertelement <4 x half> poison, half %b, i32 0 50 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer 51 %vc = call <4 x half> @llvm.experimental.constrained.fsub.v4f16(<4 x half> %va, <4 x half> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 52 ret <4 x half> %vc 53} 54 55declare <8 x half> @llvm.experimental.constrained.fsub.v8f16(<8 x half>, <8 x half>, metadata, metadata) 56define <8 x half> @vfsub_vv_v8f16(<8 x half> %va, <8 x half> %vb) strictfp { 57; CHECK-LABEL: vfsub_vv_v8f16: 58; CHECK: # %bb.0: # %entry 59; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma 60; CHECK-NEXT: vfsub.vv v8, v8, v9 61; CHECK-NEXT: ret 62entry: 63 %vc = call <8 x half> @llvm.experimental.constrained.fsub.v8f16(<8 x half> %va, <8 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 64 ret <8 x half> %vc 65} 66 67define <8 x half> @vfsub_vf_v8f16(<8 x half> %va, half %b) strictfp { 68; CHECK-LABEL: vfsub_vf_v8f16: 69; CHECK: # %bb.0: 70; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma 71; CHECK-NEXT: vfsub.vf v8, v8, fa0 72; CHECK-NEXT: ret 73 %head = insertelement <8 x half> poison, half %b, i32 0 74 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer 75 %vc = call <8 x half> @llvm.experimental.constrained.fsub.v8f16(<8 x half> %va, <8 x half> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 76 ret <8 x half> %vc 77} 78 79define <8 x half> @vfsub_fv_v8f16(<8 x half> %va, half %b) strictfp { 80; CHECK-LABEL: vfsub_fv_v8f16: 81; CHECK: # %bb.0: 82; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma 83; CHECK-NEXT: vfrsub.vf v8, v8, fa0 84; CHECK-NEXT: ret 85 %head = insertelement <8 x half> poison, half %b, i32 0 86 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer 87 %vc = call <8 x half> @llvm.experimental.constrained.fsub.v8f16(<8 x half> %splat, <8 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.ignore") 88 ret <8 x half> %vc 89} 90 91declare <16 x half> @llvm.experimental.constrained.fsub.v16f16(<16 x half>, <16 x half>, metadata, metadata) 92define <16 x half> @vfsub_vv_v16f16(<16 x half> %va, <16 x half> %vb) strictfp { 93; CHECK-LABEL: vfsub_vv_v16f16: 94; CHECK: # %bb.0: # %entry 95; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma 96; CHECK-NEXT: vfsub.vv v8, v8, v10 97; CHECK-NEXT: ret 98entry: 99 %vc = call <16 x half> @llvm.experimental.constrained.fsub.v16f16(<16 x half> %va, <16 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 100 ret <16 x half> %vc 101} 102 103define <16 x half> @vfsub_vf_v16f16(<16 x half> %va, half %b) strictfp { 104; CHECK-LABEL: vfsub_vf_v16f16: 105; CHECK: # %bb.0: 106; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma 107; CHECK-NEXT: vfsub.vf v8, v8, fa0 108; CHECK-NEXT: ret 109 %head = insertelement <16 x half> poison, half %b, i32 0 110 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer 111 %vc = call <16 x half> @llvm.experimental.constrained.fsub.v16f16(<16 x half> %va, <16 x half> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 112 ret <16 x half> %vc 113} 114 115declare <32 x half> @llvm.experimental.constrained.fsub.v32f16(<32 x half>, <32 x half>, metadata, metadata) 116define <32 x half> @vfsub_vv_v32f16(<32 x half> %va, <32 x half> %vb) strictfp { 117; CHECK-LABEL: vfsub_vv_v32f16: 118; CHECK: # %bb.0: # %entry 119; CHECK-NEXT: li a0, 32 120; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma 121; CHECK-NEXT: vfsub.vv v8, v8, v12 122; CHECK-NEXT: ret 123entry: 124 %vc = call <32 x half> @llvm.experimental.constrained.fsub.v32f16(<32 x half> %va, <32 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 125 ret <32 x half> %vc 126} 127 128define <32 x half> @vfsub_vf_v32f16(<32 x half> %va, half %b) strictfp { 129; CHECK-LABEL: vfsub_vf_v32f16: 130; CHECK: # %bb.0: 131; CHECK-NEXT: li a0, 32 132; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma 133; CHECK-NEXT: vfsub.vf v8, v8, fa0 134; CHECK-NEXT: ret 135 %head = insertelement <32 x half> poison, half %b, i32 0 136 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer 137 %vc = call <32 x half> @llvm.experimental.constrained.fsub.v32f16(<32 x half> %va, <32 x half> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 138 ret <32 x half> %vc 139} 140 141declare <2 x float> @llvm.experimental.constrained.fsub.v2f32(<2 x float>, <2 x float>, metadata, metadata) 142define <2 x float> @vfsub_vv_v2f32(<2 x float> %va, <2 x float> %vb) strictfp { 143; CHECK-LABEL: vfsub_vv_v2f32: 144; CHECK: # %bb.0: # %entry 145; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma 146; CHECK-NEXT: vfsub.vv v8, v8, v9 147; CHECK-NEXT: ret 148entry: 149 %vc = call <2 x float> @llvm.experimental.constrained.fsub.v2f32(<2 x float> %va, <2 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 150 ret <2 x float> %vc 151} 152 153define <2 x float> @vfsub_vf_v2f32(<2 x float> %va, float %b) strictfp { 154; CHECK-LABEL: vfsub_vf_v2f32: 155; CHECK: # %bb.0: 156; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma 157; CHECK-NEXT: vfsub.vf v8, v8, fa0 158; CHECK-NEXT: ret 159 %head = insertelement <2 x float> poison, float %b, i32 0 160 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer 161 %vc = call <2 x float> @llvm.experimental.constrained.fsub.v2f32(<2 x float> %va, <2 x float> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 162 ret <2 x float> %vc 163} 164 165declare <4 x float> @llvm.experimental.constrained.fsub.v4f32(<4 x float>, <4 x float>, metadata, metadata) 166define <4 x float> @vfsub_vv_v4f32(<4 x float> %va, <4 x float> %vb) strictfp { 167; CHECK-LABEL: vfsub_vv_v4f32: 168; CHECK: # %bb.0: # %entry 169; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 170; CHECK-NEXT: vfsub.vv v8, v8, v9 171; CHECK-NEXT: ret 172entry: 173 %vc = call <4 x float> @llvm.experimental.constrained.fsub.v4f32(<4 x float> %va, <4 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 174 ret <4 x float> %vc 175} 176 177define <4 x float> @vfsub_vf_v4f32(<4 x float> %va, float %b) strictfp { 178; CHECK-LABEL: vfsub_vf_v4f32: 179; CHECK: # %bb.0: 180; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 181; CHECK-NEXT: vfsub.vf v8, v8, fa0 182; CHECK-NEXT: ret 183 %head = insertelement <4 x float> poison, float %b, i32 0 184 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer 185 %vc = call <4 x float> @llvm.experimental.constrained.fsub.v4f32(<4 x float> %va, <4 x float> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 186 ret <4 x float> %vc 187} 188 189declare <8 x float> @llvm.experimental.constrained.fsub.v8f32(<8 x float>, <8 x float>, metadata, metadata) 190define <8 x float> @vfsub_vv_v8f32(<8 x float> %va, <8 x float> %vb) strictfp { 191; CHECK-LABEL: vfsub_vv_v8f32: 192; CHECK: # %bb.0: # %entry 193; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma 194; CHECK-NEXT: vfsub.vv v8, v8, v10 195; CHECK-NEXT: ret 196entry: 197 %vc = call <8 x float> @llvm.experimental.constrained.fsub.v8f32(<8 x float> %va, <8 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 198 ret <8 x float> %vc 199} 200 201define <8 x float> @vfsub_vf_v8f32(<8 x float> %va, float %b) strictfp { 202; CHECK-LABEL: vfsub_vf_v8f32: 203; CHECK: # %bb.0: 204; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma 205; CHECK-NEXT: vfsub.vf v8, v8, fa0 206; CHECK-NEXT: ret 207 %head = insertelement <8 x float> poison, float %b, i32 0 208 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer 209 %vc = call <8 x float> @llvm.experimental.constrained.fsub.v8f32(<8 x float> %va, <8 x float> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 210 ret <8 x float> %vc 211} 212 213define <8 x float> @vfsub_fv_v8f32(<8 x float> %va, float %b) strictfp { 214; CHECK-LABEL: vfsub_fv_v8f32: 215; CHECK: # %bb.0: 216; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma 217; CHECK-NEXT: vfrsub.vf v8, v8, fa0 218; CHECK-NEXT: ret 219 %head = insertelement <8 x float> poison, float %b, i32 0 220 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer 221 %vc = call <8 x float> @llvm.experimental.constrained.fsub.v8f32(<8 x float> %splat, <8 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.ignore") 222 ret <8 x float> %vc 223} 224 225declare <16 x float> @llvm.experimental.constrained.fsub.v16f32(<16 x float>, <16 x float>, metadata, metadata) 226define <16 x float> @vfsub_vv_v16f32(<16 x float> %va, <16 x float> %vb) strictfp { 227; CHECK-LABEL: vfsub_vv_v16f32: 228; CHECK: # %bb.0: # %entry 229; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma 230; CHECK-NEXT: vfsub.vv v8, v8, v12 231; CHECK-NEXT: ret 232entry: 233 %vc = call <16 x float> @llvm.experimental.constrained.fsub.v16f32(<16 x float> %va, <16 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 234 ret <16 x float> %vc 235} 236 237define <16 x float> @vfsub_vf_v16f32(<16 x float> %va, float %b) strictfp { 238; CHECK-LABEL: vfsub_vf_v16f32: 239; CHECK: # %bb.0: 240; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma 241; CHECK-NEXT: vfsub.vf v8, v8, fa0 242; CHECK-NEXT: ret 243 %head = insertelement <16 x float> poison, float %b, i32 0 244 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer 245 %vc = call <16 x float> @llvm.experimental.constrained.fsub.v16f32(<16 x float> %va, <16 x float> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 246 ret <16 x float> %vc 247} 248 249declare <2 x double> @llvm.experimental.constrained.fsub.v2f64(<2 x double>, <2 x double>, metadata, metadata) 250define <2 x double> @vfsub_vv_v2f64(<2 x double> %va, <2 x double> %vb) strictfp { 251; CHECK-LABEL: vfsub_vv_v2f64: 252; CHECK: # %bb.0: # %entry 253; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma 254; CHECK-NEXT: vfsub.vv v8, v8, v9 255; CHECK-NEXT: ret 256entry: 257 %vc = call <2 x double> @llvm.experimental.constrained.fsub.v2f64(<2 x double> %va, <2 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 258 ret <2 x double> %vc 259} 260 261define <2 x double> @vfsub_vf_v2f64(<2 x double> %va, double %b) strictfp { 262; CHECK-LABEL: vfsub_vf_v2f64: 263; CHECK: # %bb.0: 264; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma 265; CHECK-NEXT: vfsub.vf v8, v8, fa0 266; CHECK-NEXT: ret 267 %head = insertelement <2 x double> poison, double %b, i32 0 268 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer 269 %vc = call <2 x double> @llvm.experimental.constrained.fsub.v2f64(<2 x double> %va, <2 x double> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 270 ret <2 x double> %vc 271} 272 273declare <4 x double> @llvm.experimental.constrained.fsub.v4f64(<4 x double>, <4 x double>, metadata, metadata) 274define <4 x double> @vfsub_vv_v4f64(<4 x double> %va, <4 x double> %vb) strictfp { 275; CHECK-LABEL: vfsub_vv_v4f64: 276; CHECK: # %bb.0: # %entry 277; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma 278; CHECK-NEXT: vfsub.vv v8, v8, v10 279; CHECK-NEXT: ret 280entry: 281 %vc = call <4 x double> @llvm.experimental.constrained.fsub.v4f64(<4 x double> %va, <4 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 282 ret <4 x double> %vc 283} 284 285define <4 x double> @vfsub_vf_v4f64(<4 x double> %va, double %b) strictfp { 286; CHECK-LABEL: vfsub_vf_v4f64: 287; CHECK: # %bb.0: 288; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma 289; CHECK-NEXT: vfsub.vf v8, v8, fa0 290; CHECK-NEXT: ret 291 %head = insertelement <4 x double> poison, double %b, i32 0 292 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer 293 %vc = call <4 x double> @llvm.experimental.constrained.fsub.v4f64(<4 x double> %va, <4 x double> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 294 ret <4 x double> %vc 295} 296 297declare <8 x double> @llvm.experimental.constrained.fsub.v8f64(<8 x double>, <8 x double>, metadata, metadata) 298define <8 x double> @vfsub_vv_v8f64(<8 x double> %va, <8 x double> %vb) strictfp { 299; CHECK-LABEL: vfsub_vv_v8f64: 300; CHECK: # %bb.0: # %entry 301; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma 302; CHECK-NEXT: vfsub.vv v8, v8, v12 303; CHECK-NEXT: ret 304entry: 305 %vc = call <8 x double> @llvm.experimental.constrained.fsub.v8f64(<8 x double> %va, <8 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.ignore") 306 ret <8 x double> %vc 307} 308 309define <8 x double> @vfsub_vf_v8f64(<8 x double> %va, double %b) strictfp { 310; CHECK-LABEL: vfsub_vf_v8f64: 311; CHECK: # %bb.0: 312; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma 313; CHECK-NEXT: vfsub.vf v8, v8, fa0 314; CHECK-NEXT: ret 315 %head = insertelement <8 x double> poison, double %b, i32 0 316 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer 317 %vc = call <8 x double> @llvm.experimental.constrained.fsub.v8f64(<8 x double> %va, <8 x double> %splat, metadata !"round.dynamic", metadata !"fpexcept.ignore") 318 ret <8 x double> %vc 319} 320 321define <8 x double> @vfsub_fv_v8f64(<8 x double> %va, double %b) strictfp { 322; CHECK-LABEL: vfsub_fv_v8f64: 323; CHECK: # %bb.0: 324; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma 325; CHECK-NEXT: vfrsub.vf v8, v8, fa0 326; CHECK-NEXT: ret 327 %head = insertelement <8 x double> poison, double %b, i32 0 328 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer 329 %vc = call <8 x double> @llvm.experimental.constrained.fsub.v8f64(<8 x double> %splat, <8 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.ignore") 330 ret <8 x double> %vc 331} 332