1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux \ 3; RUN: -mcpu=pwr8 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr | FileCheck \ 4; RUN: --check-prefix=P8 %s 5; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux \ 6; RUN: -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr | FileCheck \ 7; RUN: --check-prefix=P9 %s 8 9; FIXME: Constrained fpext would fail if VSX feature disabled. Add no-vsx 10 11declare float @llvm.experimental.constrained.ceil.f32(float, metadata) 12declare double @llvm.experimental.constrained.ceil.f64(double, metadata) 13declare <4 x float> @llvm.experimental.constrained.ceil.v4f32(<4 x float>, metadata) 14declare <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double>, metadata) 15 16declare float @llvm.experimental.constrained.floor.f32(float, metadata) 17declare double @llvm.experimental.constrained.floor.f64(double, metadata) 18declare <4 x float> @llvm.experimental.constrained.floor.v4f32(<4 x float>, metadata) 19declare <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double>, metadata) 20 21declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata) 22declare <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(<4 x float>, metadata, metadata) 23declare <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(<2 x double>, metadata, metadata) 24 25declare <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f32(<4 x float>, metadata) 26declare <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32(<2 x float>, metadata) 27 28declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata) 29declare <4 x float> @llvm.experimental.constrained.fptrunc.v4f32.v4f64(<4 x double>, metadata, metadata) 30declare <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64(<2 x double>, metadata, metadata) 31 32declare float @llvm.experimental.constrained.round.f32(float, metadata) 33declare double @llvm.experimental.constrained.round.f64(double, metadata) 34declare <4 x float> @llvm.experimental.constrained.round.v4f32(<4 x float>, metadata) 35declare <2 x double> @llvm.experimental.constrained.round.v2f64(<2 x double>, metadata) 36 37declare float @llvm.experimental.constrained.trunc.f32(float, metadata) 38declare double @llvm.experimental.constrained.trunc.f64(double, metadata) 39declare <4 x float> @llvm.experimental.constrained.trunc.v4f32(<4 x float>, metadata) 40declare <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double>, metadata) 41 42define float @ceil_f32(float %f1) { 43; P8-LABEL: ceil_f32: 44; P8: # %bb.0: 45; P8-NEXT: xsrdpip f1, f1 46; P8-NEXT: blr 47; 48; P9-LABEL: ceil_f32: 49; P9: # %bb.0: 50; P9-NEXT: xsrdpip f1, f1 51; P9-NEXT: blr 52 %res = call float @llvm.experimental.constrained.ceil.f32( 53 float %f1, 54 metadata !"fpexcept.strict") 55 ret float %res 56} 57 58define double @ceil_f64(double %f1) { 59; P8-LABEL: ceil_f64: 60; P8: # %bb.0: 61; P8-NEXT: xsrdpip f1, f1 62; P8-NEXT: blr 63; 64; P9-LABEL: ceil_f64: 65; P9: # %bb.0: 66; P9-NEXT: xsrdpip f1, f1 67; P9-NEXT: blr 68 %res = call double @llvm.experimental.constrained.ceil.f64( 69 double %f1, 70 metadata !"fpexcept.strict") 71 ret double %res 72} 73 74define <4 x float> @ceil_v4f32(<4 x float> %vf1) { 75; P8-LABEL: ceil_v4f32: 76; P8: # %bb.0: 77; P8-NEXT: xvrspip v2, v2 78; P8-NEXT: blr 79; 80; P9-LABEL: ceil_v4f32: 81; P9: # %bb.0: 82; P9-NEXT: xvrspip v2, v2 83; P9-NEXT: blr 84 %res = call <4 x float> @llvm.experimental.constrained.ceil.v4f32( 85 <4 x float> %vf1, 86 metadata !"fpexcept.strict") 87 ret <4 x float> %res 88} 89 90define <2 x double> @ceil_v2f64(<2 x double> %vf1) { 91; P8-LABEL: ceil_v2f64: 92; P8: # %bb.0: 93; P8-NEXT: xvrdpip v2, v2 94; P8-NEXT: blr 95; 96; P9-LABEL: ceil_v2f64: 97; P9: # %bb.0: 98; P9-NEXT: xvrdpip v2, v2 99; P9-NEXT: blr 100 %res = call <2 x double> @llvm.experimental.constrained.ceil.v2f64( 101 <2 x double> %vf1, 102 metadata !"fpexcept.strict") 103 ret <2 x double> %res 104} 105 106define float @floor_f32(float %f1) { 107; P8-LABEL: floor_f32: 108; P8: # %bb.0: 109; P8-NEXT: xsrdpim f1, f1 110; P8-NEXT: blr 111; 112; P9-LABEL: floor_f32: 113; P9: # %bb.0: 114; P9-NEXT: xsrdpim f1, f1 115; P9-NEXT: blr 116 %res = call float @llvm.experimental.constrained.floor.f32( 117 float %f1, 118 metadata !"fpexcept.strict") 119 ret float %res 120} 121 122define double @floor_f64(double %f1) { 123; P8-LABEL: floor_f64: 124; P8: # %bb.0: 125; P8-NEXT: xsrdpim f1, f1 126; P8-NEXT: blr 127; 128; P9-LABEL: floor_f64: 129; P9: # %bb.0: 130; P9-NEXT: xsrdpim f1, f1 131; P9-NEXT: blr 132 %res = call double @llvm.experimental.constrained.floor.f64( 133 double %f1, 134 metadata !"fpexcept.strict") 135 ret double %res; 136} 137 138define <4 x float> @floor_v4f32(<4 x float> %vf1) { 139; P8-LABEL: floor_v4f32: 140; P8: # %bb.0: 141; P8-NEXT: xvrspim v2, v2 142; P8-NEXT: blr 143; 144; P9-LABEL: floor_v4f32: 145; P9: # %bb.0: 146; P9-NEXT: xvrspim v2, v2 147; P9-NEXT: blr 148 %res = call <4 x float> @llvm.experimental.constrained.floor.v4f32( 149 <4 x float> %vf1, 150 metadata !"fpexcept.strict") 151 ret <4 x float> %res; 152} 153 154define <2 x double> @floor_v2f64(<2 x double> %vf1) { 155; P8-LABEL: floor_v2f64: 156; P8: # %bb.0: 157; P8-NEXT: xvrdpim v2, v2 158; P8-NEXT: blr 159; 160; P9-LABEL: floor_v2f64: 161; P9: # %bb.0: 162; P9-NEXT: xvrdpim v2, v2 163; P9-NEXT: blr 164 %res = call <2 x double> @llvm.experimental.constrained.floor.v2f64( 165 <2 x double> %vf1, 166 metadata !"fpexcept.strict") 167 ret <2 x double> %res; 168} 169 170define double @nearbyint_f64(double %f1, double %f2) { 171; P8-LABEL: nearbyint_f64: 172; P8: # %bb.0: 173; P8-NEXT: xsrdpic f1, f1 174; P8-NEXT: blr 175; 176; P9-LABEL: nearbyint_f64: 177; P9: # %bb.0: 178; P9-NEXT: xsrdpic f1, f1 179; P9-NEXT: blr 180 %res = call double @llvm.experimental.constrained.nearbyint.f64( 181 double %f1, 182 metadata !"round.dynamic", 183 metadata !"fpexcept.strict") 184 ret double %res 185} 186 187define <4 x float> @nearbyint_v4f32(<4 x float> %vf1, <4 x float> %vf2) { 188; P8-LABEL: nearbyint_v4f32: 189; P8: # %bb.0: 190; P8-NEXT: xvrspic v2, v2 191; P8-NEXT: blr 192; 193; P9-LABEL: nearbyint_v4f32: 194; P9: # %bb.0: 195; P9-NEXT: xvrspic v2, v2 196; P9-NEXT: blr 197 %res = call <4 x float> @llvm.experimental.constrained.nearbyint.v4f32( 198 <4 x float> %vf1, 199 metadata !"round.dynamic", 200 metadata !"fpexcept.strict") 201 ret <4 x float> %res 202} 203 204define <2 x double> @nearbyint_v2f64(<2 x double> %vf1, <2 x double> %vf2) { 205; P8-LABEL: nearbyint_v2f64: 206; P8: # %bb.0: 207; P8-NEXT: xvrdpic v2, v2 208; P8-NEXT: blr 209; 210; P9-LABEL: nearbyint_v2f64: 211; P9: # %bb.0: 212; P9-NEXT: xvrdpic v2, v2 213; P9-NEXT: blr 214 %res = call <2 x double> @llvm.experimental.constrained.nearbyint.v2f64( 215 <2 x double> %vf1, 216 metadata !"round.dynamic", 217 metadata !"fpexcept.strict") 218 ret <2 x double> %res 219} 220 221define <4 x double> @fpext_v4f64_v4f32(<4 x float> %vf1) { 222; P8-LABEL: fpext_v4f64_v4f32: 223; P8: # %bb.0: 224; P8-NEXT: xxsldwi vs0, v2, v2, 1 225; P8-NEXT: xxsldwi vs1, v2, v2, 3 226; P8-NEXT: xxswapd vs3, v2 227; P8-NEXT: xscvspdpn f2, v2 228; P8-NEXT: xscvspdpn f0, vs0 229; P8-NEXT: xscvspdpn f1, vs1 230; P8-NEXT: xscvspdpn f3, vs3 231; P8-NEXT: xxmrghd v2, vs2, vs0 232; P8-NEXT: xxmrghd v3, vs3, vs1 233; P8-NEXT: blr 234; 235; P9-LABEL: fpext_v4f64_v4f32: 236; P9: # %bb.0: 237; P9-NEXT: xxsldwi vs0, v2, v2, 3 238; P9-NEXT: xxswapd vs1, v2 239; P9-NEXT: xscvspdpn f0, vs0 240; P9-NEXT: xscvspdpn f1, vs1 241; P9-NEXT: xxsldwi vs2, v2, v2, 1 242; P9-NEXT: xscvspdpn f2, vs2 243; P9-NEXT: xxmrghd vs0, vs1, vs0 244; P9-NEXT: xscvspdpn f1, v2 245; P9-NEXT: xxmrghd v3, vs1, vs2 246; P9-NEXT: xxlor v2, vs0, vs0 247; P9-NEXT: blr 248 %res = call <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f32( 249 <4 x float> %vf1, 250 metadata !"fpexcept.strict") 251 ret <4 x double> %res 252} 253 254define <2 x double> @fpext_v2f64_v2f32(<2 x float> %vf1) { 255; P8-LABEL: fpext_v2f64_v2f32: 256; P8: # %bb.0: 257; P8-NEXT: xxsldwi vs0, v2, v2, 1 258; P8-NEXT: xscvspdpn f1, v2 259; P8-NEXT: xscvspdpn f0, vs0 260; P8-NEXT: xxmrghd v2, vs1, vs0 261; P8-NEXT: blr 262; 263; P9-LABEL: fpext_v2f64_v2f32: 264; P9: # %bb.0: 265; P9-NEXT: xxsldwi vs0, v2, v2, 3 266; P9-NEXT: xxswapd vs1, v2 267; P9-NEXT: xscvspdpn f0, vs0 268; P9-NEXT: xscvspdpn f1, vs1 269; P9-NEXT: xxmrghd v2, vs1, vs0 270; P9-NEXT: blr 271 %res = call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32( 272 <2 x float> %vf1, 273 metadata !"fpexcept.strict") 274 ret <2 x double> %res 275} 276 277define float @fptrunc_f32_f64(double %f1) { 278; P8-LABEL: fptrunc_f32_f64: 279; P8: # %bb.0: 280; P8-NEXT: xsrsp f1, f1 281; P8-NEXT: blr 282; 283; P9-LABEL: fptrunc_f32_f64: 284; P9: # %bb.0: 285; P9-NEXT: xsrsp f1, f1 286; P9-NEXT: blr 287 %res = call float @llvm.experimental.constrained.fptrunc.f32.f64( 288 double %f1, 289 metadata !"round.dynamic", 290 metadata !"fpexcept.strict") 291 ret float %res; 292} 293 294define <4 x float> @fptrunc_v4f32_v4f64(<4 x double> %vf1) { 295; P8-LABEL: fptrunc_v4f32_v4f64: 296; P8: # %bb.0: 297; P8-NEXT: xxmrgld vs0, v2, v3 298; P8-NEXT: xxmrghd vs1, v2, v3 299; P8-NEXT: xvcvdpsp v2, vs0 300; P8-NEXT: xvcvdpsp v3, vs1 301; P8-NEXT: vmrgew v2, v3, v2 302; P8-NEXT: blr 303; 304; P9-LABEL: fptrunc_v4f32_v4f64: 305; P9: # %bb.0: 306; P9-NEXT: xxmrgld vs0, v3, v2 307; P9-NEXT: xvcvdpsp v4, vs0 308; P9-NEXT: xxmrghd vs0, v3, v2 309; P9-NEXT: xvcvdpsp v2, vs0 310; P9-NEXT: vmrgew v2, v2, v4 311; P9-NEXT: blr 312 %res = call <4 x float> @llvm.experimental.constrained.fptrunc.v4f32.v4f64( 313 <4 x double> %vf1, 314 metadata !"round.dynamic", 315 metadata !"fpexcept.strict") 316 ret <4 x float> %res 317} 318 319define <2 x float> @fptrunc_v2f32_v2f64(<2 x double> %vf1) { 320; P8-LABEL: fptrunc_v2f32_v2f64: 321; P8: # %bb.0: 322; P8-NEXT: xxswapd vs0, v2 323; P8-NEXT: xsrsp f1, v2 324; P8-NEXT: xsrsp f0, f0 325; P8-NEXT: xscvdpspn v2, f1 326; P8-NEXT: xscvdpspn v3, f0 327; P8-NEXT: vmrghw v2, v2, v3 328; P8-NEXT: blr 329; 330; P9-LABEL: fptrunc_v2f32_v2f64: 331; P9: # %bb.0: 332; P9-NEXT: xsrsp f0, v2 333; P9-NEXT: xscvdpspn vs0, f0 334; P9-NEXT: xxsldwi v3, vs0, vs0, 3 335; P9-NEXT: xxswapd vs0, v2 336; P9-NEXT: xsrsp f0, f0 337; P9-NEXT: xscvdpspn vs0, f0 338; P9-NEXT: xxsldwi v2, vs0, vs0, 3 339; P9-NEXT: vmrghw v2, v3, v2 340; P9-NEXT: blr 341 %res = call <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64( 342 <2 x double> %vf1, 343 metadata !"round.dynamic", 344 metadata !"fpexcept.strict") 345 ret <2 x float> %res 346} 347 348define float @round_f32(float %f1) { 349; P8-LABEL: round_f32: 350; P8: # %bb.0: 351; P8-NEXT: xsrdpi f1, f1 352; P8-NEXT: blr 353; 354; P9-LABEL: round_f32: 355; P9: # %bb.0: 356; P9-NEXT: xsrdpi f1, f1 357; P9-NEXT: blr 358 %res = call float @llvm.experimental.constrained.round.f32( 359 float %f1, 360 metadata !"fpexcept.strict") 361 ret float %res 362} 363 364define double @round_f64(double %f1) { 365; P8-LABEL: round_f64: 366; P8: # %bb.0: 367; P8-NEXT: xsrdpi f1, f1 368; P8-NEXT: blr 369; 370; P9-LABEL: round_f64: 371; P9: # %bb.0: 372; P9-NEXT: xsrdpi f1, f1 373; P9-NEXT: blr 374 %res = call double @llvm.experimental.constrained.round.f64( 375 double %f1, 376 metadata !"fpexcept.strict") 377 ret double %res 378} 379 380define <4 x float> @round_v4f32(<4 x float> %vf1) { 381; P8-LABEL: round_v4f32: 382; P8: # %bb.0: 383; P8-NEXT: xvrspi v2, v2 384; P8-NEXT: blr 385; 386; P9-LABEL: round_v4f32: 387; P9: # %bb.0: 388; P9-NEXT: xvrspi v2, v2 389; P9-NEXT: blr 390 %res = call <4 x float> @llvm.experimental.constrained.round.v4f32( 391 <4 x float> %vf1, 392 metadata !"fpexcept.strict") 393 ret <4 x float> %res 394} 395 396define <2 x double> @round_v2f64(<2 x double> %vf1) { 397; P8-LABEL: round_v2f64: 398; P8: # %bb.0: 399; P8-NEXT: xvrdpi v2, v2 400; P8-NEXT: blr 401; 402; P9-LABEL: round_v2f64: 403; P9: # %bb.0: 404; P9-NEXT: xvrdpi v2, v2 405; P9-NEXT: blr 406 %res = call <2 x double> @llvm.experimental.constrained.round.v2f64( 407 <2 x double> %vf1, 408 metadata !"fpexcept.strict") 409 ret <2 x double> %res 410} 411 412define float @trunc_f32(float %f1) { 413; P8-LABEL: trunc_f32: 414; P8: # %bb.0: 415; P8-NEXT: xsrdpiz f1, f1 416; P8-NEXT: blr 417; 418; P9-LABEL: trunc_f32: 419; P9: # %bb.0: 420; P9-NEXT: xsrdpiz f1, f1 421; P9-NEXT: blr 422 %res = call float @llvm.experimental.constrained.trunc.f32( 423 float %f1, 424 metadata !"fpexcept.strict") 425 ret float %res 426} 427 428define double @trunc_f64(double %f1) { 429; P8-LABEL: trunc_f64: 430; P8: # %bb.0: 431; P8-NEXT: xsrdpiz f1, f1 432; P8-NEXT: blr 433; 434; P9-LABEL: trunc_f64: 435; P9: # %bb.0: 436; P9-NEXT: xsrdpiz f1, f1 437; P9-NEXT: blr 438 %res = call double @llvm.experimental.constrained.trunc.f64( 439 double %f1, 440 metadata !"fpexcept.strict") 441 ret double %res 442} 443 444define <4 x float> @trunc_v4f32(<4 x float> %vf1) { 445; P8-LABEL: trunc_v4f32: 446; P8: # %bb.0: 447; P8-NEXT: xvrspiz v2, v2 448; P8-NEXT: blr 449; 450; P9-LABEL: trunc_v4f32: 451; P9: # %bb.0: 452; P9-NEXT: xvrspiz v2, v2 453; P9-NEXT: blr 454 %res = call <4 x float> @llvm.experimental.constrained.trunc.v4f32( 455 <4 x float> %vf1, 456 metadata !"fpexcept.strict") 457 ret <4 x float> %res 458} 459 460define <2 x double> @trunc_v2f64(<2 x double> %vf1) { 461; P8-LABEL: trunc_v2f64: 462; P8: # %bb.0: 463; P8-NEXT: xvrdpiz v2, v2 464; P8-NEXT: blr 465; 466; P9-LABEL: trunc_v2f64: 467; P9: # %bb.0: 468; P9-NEXT: xvrdpiz v2, v2 469; P9-NEXT: blr 470 %res = call <2 x double> @llvm.experimental.constrained.trunc.v2f64( 471 <2 x double> %vf1, 472 metadata !"fpexcept.strict") 473 ret <2 x double> %res 474} 475