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 5 define 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 14 define 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 23 define 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 32 define 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 41 define 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 50 define 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 59 define 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 68 define 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 77 define 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 86 define 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 95 define 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 104 define 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 113 define 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 122 define 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 131 define 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 140 define 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 151 define 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 162 define 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 173 define 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 184 define 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 195 define 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 206 define 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 217 define 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 228 define 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 239 define 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 250 define 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 261 define 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 272 define 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 283 define 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 294 define 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 305 define 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 316 define 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 327 define 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 339 define 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 351 define 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 363 define 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 375 declare <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float>, <4 x float>) nounwind readnone 376 declare <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float>, <2 x float>) nounwind readnone 377 declare <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float>, <4 x float>) nounwind readnone 378 declare <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float>, <2 x float>) nounwind readnone 379