1 ; This file checks support for comparing vector values with the fcmp 2 ; instruction. 3 4 ; RUN: %p2i -i %s --filetype=obj --disassemble -a -O2 | FileCheck %s 5 ; RUN: %p2i -i %s --filetype=obj --disassemble -a -Om1 | FileCheck %s 6 7 ; RUN: %if --need=target_MIPS32 --need=allow_dump \ 8 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\ 9 ; RUN: -i %s --args -O2 \ 10 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \ 11 ; RUN: --command FileCheck --check-prefix MIPS32 %s 12 13 ; Check that sext elimination occurs when the result of the comparison 14 ; instruction is alrady sign extended. Sign extension to 4 x i32 uses 15 ; the pslld instruction. 16 define internal <4 x i32> @sextElimination(<4 x float> %a, <4 x float> %b) { 17 entry: 18 %res.trunc = fcmp oeq <4 x float> %a, %b 19 %res = sext <4 x i1> %res.trunc to <4 x i32> 20 ret <4 x i32> %res 21 ; CHECK-LABEL: sextElimination 22 ; CHECK: cmpeqps 23 ; CHECK-NOT: pslld 24 } 25 ; MIPS32-LABEL: sextElimination 26 ; MIPS32: c.eq.s 27 ; MIPS32: li [[R:.*]],1 28 ; MIPS32: movf [[R]],zero,$fcc0 29 ; MIPS32: c.eq.s 30 ; MIPS32: li [[R:.*]],1 31 ; MIPS32: movf [[R]],zero,$fcc0 32 ; MIPS32: c.eq.s 33 ; MIPS32: li [[R:.*]],1 34 ; MIPS32: movf [[R]],zero,$fcc0 35 ; MIPS32: c.eq.s 36 ; MIPS32: li [[R:.*]],1 37 ; MIPS32: movf [[R]],zero,$fcc0 38 39 define internal <4 x i32> @fcmpFalseVector(<4 x float> %a, <4 x float> %b) { 40 entry: 41 %res.trunc = fcmp false <4 x float> %a, %b 42 %res = sext <4 x i1> %res.trunc to <4 x i32> 43 ret <4 x i32> %res 44 ; CHECK-LABEL: fcmpFalseVector 45 ; CHECK: pxor 46 } 47 ; MIPS32-LABEL: fcmpFalseVector 48 ; MIPS32: li v0,0 49 ; MIPS32: li v1,0 50 ; MIPS32: li a0,0 51 ; MIPS32: li a1,0 52 53 define internal <4 x i32> @fcmpOeqVector(<4 x float> %a, <4 x float> %b) { 54 entry: 55 %res.trunc = fcmp oeq <4 x float> %a, %b 56 %res = sext <4 x i1> %res.trunc to <4 x i32> 57 ret <4 x i32> %res 58 ; CHECK-LABEL: fcmpOeqVector 59 ; CHECK: cmpeqps 60 } 61 ; MIPS32-LABEL: fcmpOeqVector 62 ; MIPS32: c.eq.s 63 ; MIPS32: li [[R:.*]],1 64 ; MIPS32: movf [[R]],zero,$fcc0 65 ; MIPS32: c.eq.s 66 ; MIPS32: li [[R:.*]],1 67 ; MIPS32: movf [[R]],zero,$fcc0 68 ; MIPS32: c.eq.s 69 ; MIPS32: li [[R:.*]],1 70 ; MIPS32: movf [[R]],zero,$fcc0 71 ; MIPS32: c.eq.s 72 ; MIPS32: li [[R:.*]],1 73 ; MIPS32: movf [[R]],zero,$fcc0 74 75 define internal <4 x i32> @fcmpOgeVector(<4 x float> %a, <4 x float> %b) { 76 entry: 77 %res.trunc = fcmp oge <4 x float> %a, %b 78 %res = sext <4 x i1> %res.trunc to <4 x i32> 79 ret <4 x i32> %res 80 ; CHECK-LABEL: fcmpOgeVector 81 ; CHECK: cmpleps 82 } 83 ; MIPS32-LABEL: fcmpOgeVector 84 ; MIPS32: c.ult.s 85 ; MIPS32: li [[R:.*]],1 86 ; MIPS32: movt [[R]],zero,$fcc0 87 ; MIPS32: c.ult.s 88 ; MIPS32: li [[R:.*]],1 89 ; MIPS32: movt [[R]],zero,$fcc0 90 ; MIPS32: c.ult.s 91 ; MIPS32: li [[R:.*]],1 92 ; MIPS32: movt [[R]],zero,$fcc0 93 ; MIPS32: c.ult.s 94 ; MIPS32: li [[R:.*]],1 95 ; MIPS32: movt [[R]],zero,$fcc0 96 97 define internal <4 x i32> @fcmpOgtVector(<4 x float> %a, <4 x float> %b) { 98 entry: 99 %res.trunc = fcmp ogt <4 x float> %a, %b 100 %res = sext <4 x i1> %res.trunc to <4 x i32> 101 ret <4 x i32> %res 102 ; CHECK-LABEL: fcmpOgtVector 103 ; CHECK: cmpltps 104 } 105 ; MIPS32-LABEL: fcmpOgtVector 106 ; MIPS32: c.ule.s 107 ; MIPS32: li [[R:.*]],1 108 ; MIPS32: movt [[R]],zero,$fcc0 109 ; MIPS32: c.ule.s 110 ; MIPS32: li [[R:.*]],1 111 ; MIPS32: movt [[R]],zero,$fcc0 112 ; MIPS32: c.ule.s 113 ; MIPS32: li [[R:.*]],1 114 ; MIPS32: movt [[R]],zero,$fcc0 115 ; MIPS32: c.ule.s 116 ; MIPS32: li [[R:.*]],1 117 ; MIPS32: movt [[R]],zero,$fcc0 118 119 define internal <4 x i32> @fcmpOleVector(<4 x float> %a, <4 x float> %b) { 120 entry: 121 %res.trunc = fcmp ole <4 x float> %a, %b 122 %res = sext <4 x i1> %res.trunc to <4 x i32> 123 ret <4 x i32> %res 124 ; CHECK-LABEL: fcmpOleVector 125 ; CHECK: cmpleps 126 } 127 ; MIPS32-LABEL: fcmpOleVector 128 ; MIPS32: c.ole.s 129 ; MIPS32: li [[R:.*]],1 130 ; MIPS32: movf [[R]],zero,$fcc0 131 ; MIPS32: c.ole.s 132 ; MIPS32: li [[R:.*]],1 133 ; MIPS32: movf [[R]],zero,$fcc0 134 ; MIPS32: c.ole.s 135 ; MIPS32: li [[R:.*]],1 136 ; MIPS32: movf [[R]],zero,$fcc0 137 ; MIPS32: c.ole.s 138 ; MIPS32: li [[R:.*]],1 139 ; MIPS32: movf [[R]],zero,$fcc0 140 141 define internal <4 x i32> @fcmpOltVector(<4 x float> %a, <4 x float> %b) { 142 entry: 143 %res.trunc = fcmp olt <4 x float> %a, %b 144 %res = sext <4 x i1> %res.trunc to <4 x i32> 145 ret <4 x i32> %res 146 ; CHECK-LABEL: fcmpOltVector 147 ; CHECK: cmpltps 148 } 149 ; MIPS32-LABEL: fcmpOltVector 150 ; MIPS32: c.olt.s 151 ; MIPS32: li [[R:.*]],1 152 ; MIPS32: movf [[R]],zero,$fcc0 153 ; MIPS32: c.olt.s 154 ; MIPS32: li [[R:.*]],1 155 ; MIPS32: movf [[R]],zero,$fcc0 156 ; MIPS32: c.olt.s 157 ; MIPS32: li [[R:.*]],1 158 ; MIPS32: movf [[R]],zero,$fcc0 159 ; MIPS32: c.olt.s 160 ; MIPS32: li [[R:.*]],1 161 ; MIPS32: movf [[R]],zero,$fcc0 162 163 define internal <4 x i32> @fcmpOneVector(<4 x float> %a, <4 x float> %b) { 164 entry: 165 %res.trunc = fcmp one <4 x float> %a, %b 166 %res = sext <4 x i1> %res.trunc to <4 x i32> 167 ret <4 x i32> %res 168 ; CHECK-LABEL: fcmpOneVector 169 ; CHECK: cmpneqps 170 ; CHECK: cmpordps 171 ; CHECK: pand 172 } 173 ; MIPS32-LABEL: fcmpOneVector 174 ; MIPS32: c.ueq.s 175 ; MIPS32: li [[R:.*]],1 176 ; MIPS32: movt [[R]],zero,$fcc0 177 ; MIPS32: c.ueq.s 178 ; MIPS32: li [[R:.*]],1 179 ; MIPS32: movt [[R]],zero,$fcc0 180 ; MIPS32: c.ueq.s 181 ; MIPS32: li [[R:.*]],1 182 ; MIPS32: movt [[R]],zero,$fcc0 183 ; MIPS32: c.ueq.s 184 ; MIPS32: li [[R:.*]],1 185 ; MIPS32: movt [[R]],zero,$fcc0 186 187 define internal <4 x i32> @fcmpOrdVector(<4 x float> %a, <4 x float> %b) { 188 entry: 189 %res.trunc = fcmp ord <4 x float> %a, %b 190 %res = sext <4 x i1> %res.trunc to <4 x i32> 191 ret <4 x i32> %res 192 ; CHECK-LABEL: fcmpOrdVector 193 ; CHECK: cmpordps 194 } 195 ; MIPS32-LABEL: fcmpOrdVector 196 ; MIPS32: c.un.s 197 ; MIPS32: li [[R:.*]],1 198 ; MIPS32: movt [[R]],zero,$fcc0 199 ; MIPS32: c.un.s 200 ; MIPS32: li [[R:.*]],1 201 ; MIPS32: movt [[R]],zero,$fcc0 202 ; MIPS32: c.un.s 203 ; MIPS32: li [[R:.*]],1 204 ; MIPS32: movt [[R]],zero,$fcc0 205 ; MIPS32: c.un.s 206 ; MIPS32: li [[R:.*]],1 207 ; MIPS32: movt [[R]],zero,$fcc0 208 209 define internal <4 x i32> @fcmpTrueVector(<4 x float> %a, <4 x float> %b) { 210 entry: 211 %res.trunc = fcmp true <4 x float> %a, %b 212 %res = sext <4 x i1> %res.trunc to <4 x i32> 213 ret <4 x i32> %res 214 ; CHECK-LABEL: fcmpTrueVector 215 ; CHECK: pcmpeqd 216 } 217 ; MIPS32-LABEL: fcmpTrueVector 218 ; MIPS32: li v0,1 219 ; MIPS32: li v1,1 220 ; MIPS32: li a0,1 221 ; MIPS32: li a1,1 222 223 define internal <4 x i32> @fcmpUeqVector(<4 x float> %a, <4 x float> %b) { 224 entry: 225 %res.trunc = fcmp ueq <4 x float> %a, %b 226 %res = sext <4 x i1> %res.trunc to <4 x i32> 227 ret <4 x i32> %res 228 ; CHECK-LABEL: fcmpUeqVector 229 ; CHECK: cmpeqps 230 ; CHECK: cmpunordps 231 ; CHECK: por 232 } 233 ; MIPS32-LABEL: fcmpUeqVector 234 ; MIPS32: c.ueq.s 235 ; MIPS32: li [[R:.*]],1 236 ; MIPS32: movf [[R]],zero,$fcc0 237 ; MIPS32: c.ueq.s 238 ; MIPS32: li [[R:.*]],1 239 ; MIPS32: movf [[R]],zero,$fcc0 240 ; MIPS32: c.ueq.s 241 ; MIPS32: li [[R:.*]],1 242 ; MIPS32: movf [[R]],zero,$fcc0 243 ; MIPS32: c.ueq.s 244 ; MIPS32: li [[R:.*]],1 245 ; MIPS32: movf [[R]],zero,$fcc0 246 247 define internal <4 x i32> @fcmpUgeVector(<4 x float> %a, <4 x float> %b) { 248 entry: 249 %res.trunc = fcmp uge <4 x float> %a, %b 250 %res = sext <4 x i1> %res.trunc to <4 x i32> 251 ret <4 x i32> %res 252 ; CHECK-LABEL: fcmpUgeVector 253 ; CHECK: cmpnltps 254 } 255 ; MIPS32-LABEL: fcmpUgeVector 256 ; MIPS32: c.olt.s 257 ; MIPS32: li [[R:.*]],1 258 ; MIPS32: movt [[R]],zero,$fcc0 259 ; MIPS32: c.olt.s 260 ; MIPS32: li [[R:.*]],1 261 ; MIPS32: movt [[R]],zero,$fcc0 262 ; MIPS32: c.olt.s 263 ; MIPS32: li [[R:.*]],1 264 ; MIPS32: movt [[R]],zero,$fcc0 265 ; MIPS32: c.olt.s 266 ; MIPS32: li [[R:.*]],1 267 ; MIPS32: movt [[R]],zero,$fcc0 268 269 define internal <4 x i32> @fcmpUgtVector(<4 x float> %a, <4 x float> %b) { 270 entry: 271 %res.trunc = fcmp ugt <4 x float> %a, %b 272 %res = sext <4 x i1> %res.trunc to <4 x i32> 273 ret <4 x i32> %res 274 ; CHECK-LABEL: fcmpUgtVector 275 ; CHECK: cmpnleps 276 } 277 ; MIPS32-LABEL: fcmpUgtVector 278 ; MIPS32: c.ole.s 279 ; MIPS32: li [[R:.*]],1 280 ; MIPS32: movt [[R]],zero,$fcc0 281 ; MIPS32: c.ole.s 282 ; MIPS32: li [[R:.*]],1 283 ; MIPS32: movt [[R]],zero,$fcc0 284 ; MIPS32: c.ole.s 285 ; MIPS32: li [[R:.*]],1 286 ; MIPS32: movt [[R]],zero,$fcc0 287 ; MIPS32: c.ole.s 288 ; MIPS32: li [[R:.*]],1 289 ; MIPS32: movt [[R]],zero,$fcc0 290 291 define internal <4 x i32> @fcmpUleVector(<4 x float> %a, <4 x float> %b) { 292 entry: 293 %res.trunc = fcmp ule <4 x float> %a, %b 294 %res = sext <4 x i1> %res.trunc to <4 x i32> 295 ret <4 x i32> %res 296 ; CHECK-LABEL: fcmpUleVector 297 ; CHECK: cmpnltps 298 } 299 ; MIPS32-LABEL: fcmpUleVector 300 ; MIPS32: c.ule.s 301 ; MIPS32: li [[R:.*]],1 302 ; MIPS32: movf [[R]],zero,$fcc0 303 ; MIPS32: c.ule.s 304 ; MIPS32: li [[R:.*]],1 305 ; MIPS32: movf [[R]],zero,$fcc0 306 ; MIPS32: c.ule.s 307 ; MIPS32: li [[R:.*]],1 308 ; MIPS32: movf [[R]],zero,$fcc0 309 ; MIPS32: c.ule.s 310 ; MIPS32: li [[R:.*]],1 311 ; MIPS32: movf [[R]],zero,$fcc0 312 313 define internal <4 x i32> @fcmpUltVector(<4 x float> %a, <4 x float> %b) { 314 entry: 315 %res.trunc = fcmp ult <4 x float> %a, %b 316 %res = sext <4 x i1> %res.trunc to <4 x i32> 317 ret <4 x i32> %res 318 ; CHECK-LABEL: fcmpUltVector 319 ; CHECK: cmpnleps 320 } 321 ; MIPS32-LABEL: fcmpUltVector 322 ; MIPS32: c.ult.s 323 ; MIPS32: li [[R:.*]],1 324 ; MIPS32: movf [[R]],zero,$fcc0 325 ; MIPS32: c.ult.s 326 ; MIPS32: li [[R:.*]],1 327 ; MIPS32: movf [[R]],zero,$fcc0 328 ; MIPS32: c.ult.s 329 ; MIPS32: li [[R:.*]],1 330 ; MIPS32: movf [[R]],zero,$fcc0 331 ; MIPS32: c.ult.s 332 ; MIPS32: li [[R:.*]],1 333 ; MIPS32: movf [[R]],zero,$fcc0 334 335 define internal <4 x i32> @fcmpUneVector(<4 x float> %a, <4 x float> %b) { 336 entry: 337 %res.trunc = fcmp une <4 x float> %a, %b 338 %res = sext <4 x i1> %res.trunc to <4 x i32> 339 ret <4 x i32> %res 340 ; CHECK-LABEL: fcmpUneVector 341 ; CHECK: cmpneqps 342 } 343 ; MIPS32-LABEL: fcmpUneVector 344 ; MIPS32: c.eq.s 345 ; MIPS32: li [[R:.*]],1 346 ; MIPS32: movt [[R]],zero,$fcc0 347 ; MIPS32: c.eq.s 348 ; MIPS32: li [[R:.*]],1 349 ; MIPS32: movt [[R]],zero,$fcc0 350 ; MIPS32: c.eq.s 351 ; MIPS32: li [[R:.*]],1 352 ; MIPS32: movt [[R]],zero,$fcc0 353 ; MIPS32: c.eq.s 354 ; MIPS32: li [[R:.*]],1 355 ; MIPS32: movt [[R]],zero,$fcc0 356 357 define internal <4 x i32> @fcmpUnoVector(<4 x float> %a, <4 x float> %b) { 358 entry: 359 %res.trunc = fcmp uno <4 x float> %a, %b 360 %res = sext <4 x i1> %res.trunc to <4 x i32> 361 ret <4 x i32> %res 362 ; CHECK-LABEL: fcmpUnoVector 363 ; CHECK: cmpunordps 364 } 365 ; MIPS32-LABEL: fcmpUnoVector 366 ; MIPS32: c.un.s 367 ; MIPS32: li [[R:.*]],1 368 ; MIPS32: movf [[R]],zero,$fcc0 369 ; MIPS32: c.un.s 370 ; MIPS32: li [[R:.*]],1 371 ; MIPS32: movf [[R]],zero,$fcc0 372 ; MIPS32: c.un.s 373 ; MIPS32: li [[R:.*]],1 374 ; MIPS32: movf [[R]],zero,$fcc0 375 ; MIPS32: c.un.s 376 ; MIPS32: li [[R:.*]],1 377 ; MIPS32: movf [[R]],zero,$fcc0 378