1; RUN: llc < %s -mtriple armv8 -mattr=+neon,+fp-armv8 -enable-unsafe-fp-math -enable-no-nans-fp-math | FileCheck %s 2 3; scalars 4 5define float @fp-armv8_vminnm_o(float %a, float %b) { 6; CHECK-LABEL: "fp-armv8_vminnm_o": 7; CHECK-NOT: vcmp 8; CHECK: vminnm.f32 9 %cmp = fcmp fast olt float %a, %b 10 %cond = select i1 %cmp, float %a, float %b 11 ret float %cond 12} 13 14define double @fp-armv8_vminnm_ole(double %a, double %b) { 15; CHECK-LABEL: "fp-armv8_vminnm_ole": 16; CHECK-NOT: vcmp 17; CHECK: vminnm.f64 18 %cmp = fcmp fast ole double %a, %b 19 %cond = select i1 %cmp, double %a, double %b 20 ret double %cond 21} 22 23define float @fp-armv8_vminnm_o_rev(float %a, float %b) { 24; CHECK-LABEL: "fp-armv8_vminnm_o_rev": 25; CHECK-NOT: vcmp 26; CHECK: vminnm.f32 27 %cmp = fcmp fast ogt float %a, %b 28 %cond = select i1 %cmp, float %b, float %a 29 ret float %cond 30} 31 32define double @fp-armv8_vminnm_oge_rev(double %a, double %b) { 33; CHECK-LABEL: "fp-armv8_vminnm_oge_rev": 34; CHECK-NOT: vcmp 35; CHECK: vminnm.f64 36 %cmp = fcmp fast oge double %a, %b 37 %cond = select i1 %cmp, double %b, double %a 38 ret double %cond 39} 40 41define float @fp-armv8_vminnm_u(float %a, float %b) { 42; CHECK-LABEL: "fp-armv8_vminnm_u": 43; CHECK-NOT: vcmp 44; CHECK: vminnm.f32 45 %cmp = fcmp fast ult float %a, %b 46 %cond = select i1 %cmp, float %a, float %b 47 ret float %cond 48} 49 50define float @fp-armv8_vminnm_ule(float %a, float %b) { 51; CHECK-LABEL: "fp-armv8_vminnm_ule": 52; CHECK-NOT: vcmp 53; CHECK: vminnm.f32 54 %cmp = fcmp fast ule float %a, %b 55 %cond = select i1 %cmp, float %a, float %b 56 ret float %cond 57} 58 59define float @fp-armv8_vminnm_u_rev(float %a, float %b) { 60; CHECK-LABEL: "fp-armv8_vminnm_u_rev": 61; CHECK-NOT: vcmp 62; CHECK: vminnm.f32 63 %cmp = fcmp fast ugt float %a, %b 64 %cond = select i1 %cmp, float %b, float %a 65 ret float %cond 66} 67 68define double @fp-armv8_vminnm_uge_rev(double %a, double %b) { 69; CHECK-LABEL: "fp-armv8_vminnm_uge_rev": 70; CHECK-NOT: vcmp 71; CHECK: vminnm.f64 72 %cmp = fcmp fast uge double %a, %b 73 %cond = select i1 %cmp, double %b, double %a 74 ret double %cond 75} 76 77define float @fp-armv8_vmaxnm_o(float %a, float %b) { 78; CHECK-LABEL: "fp-armv8_vmaxnm_o": 79; CHECK-NOT: vcmp 80; CHECK: vmaxnm.f32 81 %cmp = fcmp fast ogt float %a, %b 82 %cond = select i1 %cmp, float %a, float %b 83 ret float %cond 84} 85 86define float @fp-armv8_vmaxnm_oge(float %a, float %b) { 87; CHECK-LABEL: "fp-armv8_vmaxnm_oge": 88; CHECK-NOT: vcmp 89; CHECK: vmaxnm.f32 90 %cmp = fcmp fast oge float %a, %b 91 %cond = select i1 %cmp, float %a, float %b 92 ret float %cond 93} 94 95define float @fp-armv8_vmaxnm_o_rev(float %a, float %b) { 96; CHECK-LABEL: "fp-armv8_vmaxnm_o_rev": 97; CHECK-NOT: vcmp 98; CHECK: vmaxnm.f32 99 %cmp = fcmp fast olt float %a, %b 100 %cond = select i1 %cmp, float %b, float %a 101 ret float %cond 102} 103 104define float @fp-armv8_vmaxnm_ole_rev(float %a, float %b) { 105; CHECK-LABEL: "fp-armv8_vmaxnm_ole_rev": 106; CHECK-NOT: vcmp 107; CHECK: vmaxnm.f32 108 %cmp = fcmp fast ole float %a, %b 109 %cond = select i1 %cmp, float %b, float %a 110 ret float %cond 111} 112 113define float @fp-armv8_vmaxnm_u(float %a, float %b) { 114; CHECK-LABEL: "fp-armv8_vmaxnm_u": 115; CHECK-NOT: vcmp 116; CHECK: vmaxnm.f32 117 %cmp = fcmp fast ugt float %a, %b 118 %cond = select i1 %cmp, float %a, float %b 119 ret float %cond 120} 121 122define float @fp-armv8_vmaxnm_uge(float %a, float %b) { 123; CHECK-LABEL: "fp-armv8_vmaxnm_uge": 124; CHECK-NOT: vcmp 125; CHECK: vmaxnm.f32 126 %cmp = fcmp fast uge float %a, %b 127 %cond = select i1 %cmp, float %a, float %b 128 ret float %cond 129} 130 131define float @fp-armv8_vmaxnm_u_rev(float %a, float %b) { 132; CHECK-LABEL: "fp-armv8_vmaxnm_u_rev": 133; CHECK-NOT: vcmp 134; CHECK: vmaxnm.f32 135 %cmp = fcmp fast ult float %a, %b 136 %cond = select i1 %cmp, float %b, float %a 137 ret float %cond 138} 139 140define double @fp-armv8_vmaxnm_ule_rev(double %a, double %b) { 141; CHECK-LABEL: "fp-armv8_vmaxnm_ule_rev": 142; CHECK-NOT: vcmp 143; CHECK: vmaxnm.f64 144 %cmp = fcmp fast ule double %a, %b 145 %cond = select i1 %cmp, double %b, double %a 146 ret double %cond 147} 148 149; known non-NaNs 150 151define float @fp-armv8_vminnm_NNNo(float %a) { 152; CHECK-LABEL: "fp-armv8_vminnm_NNNo": 153; CHECK: vminnm.f32 154; CHECK: vminnm.f32 155 %cmp1 = fcmp fast olt float %a, 12. 156 %cond1 = select i1 %cmp1, float %a, float 12. 157 %cmp2 = fcmp fast olt float 34., %cond1 158 %cond2 = select i1 %cmp2, float 34., float %cond1 159 ret float %cond2 160} 161 162define double @fp-armv8_vminnm_NNNole(double %a) { 163; CHECK-LABEL: "fp-armv8_vminnm_NNNole": 164; CHECK: vminnm.f64 165; CHECK: vminnm.f64 166 %cmp1 = fcmp fast ole double %a, 34. 167 %cond1 = select i1 %cmp1, double %a, double 34. 168 %cmp2 = fcmp fast ole double 56., %cond1 169 %cond2 = select i1 %cmp2, double 56., double %cond1 170 ret double %cond2 171} 172 173define float @fp-armv8_vminnm_NNNo_rev(float %a) { 174; CHECK-LABEL: "fp-armv8_vminnm_NNNo_rev": 175; CHECK: vminnm.f32 176; CHECK: vminnm.f32 177 %cmp1 = fcmp fast ogt float %a, 56. 178 %cond1 = select i1 %cmp1, float 56., float %a 179 %cmp2 = fcmp fast ogt float 78., %cond1 180 %cond2 = select i1 %cmp2, float %cond1, float 78. 181 ret float %cond2 182} 183 184define double @fp-armv8_vminnm_NNNoge_rev(double %a) { 185; CHECK-LABEL: "fp-armv8_vminnm_NNNoge_rev": 186; CHECK: vminnm.f64 187; CHECK: vminnm.f64 188 %cmp1 = fcmp fast oge double %a, 78. 189 %cond1 = select i1 %cmp1, double 78., double %a 190 %cmp2 = fcmp fast oge double 90., %cond1 191 %cond2 = select i1 %cmp2, double %cond1, double 90. 192 ret double %cond2 193} 194 195define float @fp-armv8_vminnm_NNNu(float %b) { 196; CHECK-LABEL: "fp-armv8_vminnm_NNNu": 197; CHECK: vminnm.f32 198; CHECK: vminnm.f32 199 %cmp1 = fcmp fast ult float 12., %b 200 %cond1 = select i1 %cmp1, float 12., float %b 201 %cmp2 = fcmp fast ult float %cond1, 34. 202 %cond2 = select i1 %cmp2, float %cond1, float 34. 203 ret float %cond2 204} 205 206define float @fp-armv8_vminnm_NNNule(float %b) { 207; CHECK-LABEL: "fp-armv8_vminnm_NNNule": 208; CHECK: vminnm.f32 209; CHECK: vminnm.f32 210 %cmp1 = fcmp fast ule float 34., %b 211 %cond1 = select i1 %cmp1, float 34., float %b 212 %cmp2 = fcmp fast ule float %cond1, 56. 213 %cond2 = select i1 %cmp2, float %cond1, float 56. 214 ret float %cond2 215} 216 217define float @fp-armv8_vminnm_NNNu_rev(float %b) { 218; CHECK-LABEL: "fp-armv8_vminnm_NNNu_rev": 219; CHECK: vminnm.f32 220; CHECK: vminnm.f32 221 %cmp1 = fcmp fast ugt float 56., %b 222 %cond1 = select i1 %cmp1, float %b, float 56. 223 %cmp2 = fcmp fast ugt float %cond1, 78. 224 %cond2 = select i1 %cmp2, float 78., float %cond1 225 ret float %cond2 226} 227 228define double @fp-armv8_vminnm_NNNuge_rev(double %b) { 229; CHECK-LABEL: "fp-armv8_vminnm_NNNuge_rev": 230; CHECK: vminnm.f64 231; CHECK: vminnm.f64 232 %cmp1 = fcmp fast uge double 78., %b 233 %cond1 = select i1 %cmp1, double %b, double 78. 234 %cmp2 = fcmp fast uge double %cond1, 90. 235 %cond2 = select i1 %cmp2, double 90., double %cond1 236 ret double %cond2 237} 238 239define float @fp-armv8_vmaxnm_NNNo(float %a) { 240; CHECK-LABEL: "fp-armv8_vmaxnm_NNNo": 241; CHECK: vmaxnm.f32 242; CHECK: vmaxnm.f32 243 %cmp1 = fcmp fast ogt float %a, 12. 244 %cond1 = select i1 %cmp1, float %a, float 12. 245 %cmp2 = fcmp fast ogt float 34., %cond1 246 %cond2 = select i1 %cmp2, float 34., float %cond1 247 ret float %cond2 248} 249 250define float @fp-armv8_vmaxnm_NNNoge(float %a) { 251; CHECK-LABEL: "fp-armv8_vmaxnm_NNNoge": 252; CHECK: vmaxnm.f32 253; CHECK: vmaxnm.f32 254 %cmp1 = fcmp fast oge float %a, 34. 255 %cond1 = select i1 %cmp1, float %a, float 34. 256 %cmp2 = fcmp fast oge float 56., %cond1 257 %cond2 = select i1 %cmp2, float 56., float %cond1 258 ret float %cond2 259} 260 261define float @fp-armv8_vmaxnm_NNNo_rev(float %a) { 262; CHECK-LABEL: "fp-armv8_vmaxnm_NNNo_rev": 263; CHECK: vmaxnm.f32 264; CHECK: vmaxnm.f32 265 %cmp1 = fcmp fast olt float %a, 56. 266 %cond1 = select i1 %cmp1, float 56., float %a 267 %cmp2 = fcmp fast olt float 78., %cond1 268 %cond2 = select i1 %cmp2, float %cond1, float 78. 269 ret float %cond2 270} 271 272define float @fp-armv8_vmaxnm_NNNole_rev(float %a) { 273; CHECK-LABEL: "fp-armv8_vmaxnm_NNNole_rev": 274; CHECK: vmaxnm.f32 275; CHECK: vmaxnm.f32 276 %cmp1 = fcmp fast ole float %a, 78. 277 %cond1 = select i1 %cmp1, float 78., float %a 278 %cmp2 = fcmp fast ole float 90., %cond1 279 %cond2 = select i1 %cmp2, float %cond1, float 90. 280 ret float %cond2 281} 282 283define float @fp-armv8_vmaxnm_NNNu(float %b) { 284; CHECK-LABEL: "fp-armv8_vmaxnm_NNNu": 285; CHECK: vmaxnm.f32 286; CHECK: vmaxnm.f32 287 %cmp1 = fcmp fast ugt float 12., %b 288 %cond1 = select i1 %cmp1, float 12., float %b 289 %cmp2 = fcmp fast ugt float %cond1, 34. 290 %cond2 = select i1 %cmp2, float %cond1, float 34. 291 ret float %cond2 292} 293 294define float @fp-armv8_vmaxnm_NNNuge(float %b) { 295; CHECK-LABEL: "fp-armv8_vmaxnm_NNNuge": 296; CHECK: vmaxnm.f32 297; CHECK: vmaxnm.f32 298 %cmp1 = fcmp fast uge float 34., %b 299 %cond1 = select i1 %cmp1, float 34., float %b 300 %cmp2 = fcmp fast uge float %cond1, 56. 301 %cond2 = select i1 %cmp2, float %cond1, float 56. 302 ret float %cond2 303} 304 305define float @fp-armv8_vmaxnm_NNNu_rev(float %b) { 306; CHECK-LABEL: "fp-armv8_vmaxnm_NNNu_rev": 307; CHECK: vmaxnm.f32 308; CHECK: vmaxnm.f32 309 %cmp1 = fcmp fast ult float 56., %b 310 %cond1 = select i1 %cmp1, float %b, float 56. 311 %cmp2 = fcmp fast ult float %cond1, 78. 312 %cond2 = select i1 %cmp2, float 78., float %cond1 313 ret float %cond2 314} 315 316define double @fp-armv8_vmaxnm_NNNule_rev( double %b) { 317; CHECK-LABEL: "fp-armv8_vmaxnm_NNNule_rev": 318; CHECK: vmaxnm.f64 319; CHECK: vmaxnm.f64 320 %cmp1 = fcmp fast ule double 78., %b 321 %cond1 = select i1 %cmp1, double %b, double 78. 322 %cmp2 = fcmp fast ule double %cond1, 90. 323 %cond2 = select i1 %cmp2, double 90., double %cond1 324 ret double %cond2 325} 326 327define float @fp-armv8_vminmaxnm_0(float %a) { 328; CHECK-LABEL: "fp-armv8_vminmaxnm_0": 329; CHECK-NOT: vcmp 330; CHECK: vminnm.f32 331; CHECK: vmaxnm.f32 332 %cmp1 = fcmp fast olt float %a, 0. 333 %cond1 = select i1 %cmp1, float %a, float 0. 334 %cmp2 = fcmp fast ogt float %cond1, 0. 335 %cond2 = select i1 %cmp2, float %cond1, float 0. 336 ret float %cond2 337} 338 339define float @fp-armv8_vminmaxnm_neg0(float %a) { 340; CHECK-LABEL: "fp-armv8_vminmaxnm_neg0": 341; CHECK-NOT: vcmp 342; CHECK: vminnm.f32 343; CHECK: vmaxnm.f32 344 %cmp1 = fcmp fast olt float %a, -0. 345 %cond1 = select i1 %cmp1, float %a, float -0. 346 %cmp2 = fcmp fast ugt float %cond1, -0. 347 %cond2 = select i1 %cmp2, float %cond1, float -0. 348 ret float %cond2 349} 350 351define float @fp-armv8_vminmaxnm_e_0(float %a) { 352; CHECK-LABEL: "fp-armv8_vminmaxnm_e_0": 353; CHECK-NOT: vcmp 354; CHECK: vminnm.f32 355; CHECK: vmaxnm.f32 356 %cmp1 = fcmp fast ule float 0., %a 357 %cond1 = select i1 %cmp1, float 0., float %a 358 %cmp2 = fcmp fast uge float 0., %cond1 359 %cond2 = select i1 %cmp2, float 0., float %cond1 360 ret float %cond2 361} 362 363define float @fp-armv8_vminmaxnm_e_neg0(float %a) { 364; CHECK-LABEL: "fp-armv8_vminmaxnm_e_neg0": 365; CHECK-NOT: vcmp 366; CHECK: vminnm.f32 367; CHECK: vmaxnm.f32 368 %cmp1 = fcmp fast ule float -0., %a 369 %cond1 = select i1 %cmp1, float -0., float %a 370 %cmp2 = fcmp fast oge float -0., %cond1 371 %cond2 = select i1 %cmp2, float -0., float %cond1 372 ret float %cond2 373} 374 375declare <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float>, <4 x float>) nounwind readnone 376declare <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float>, <2 x float>) nounwind readnone 377declare <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float>, <4 x float>) nounwind readnone 378declare <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float>, <2 x float>) nounwind readnone 379