llvm.org GIT mirror llvm / ebe4334
[EarlyCSE] add tests for selects with commuted operands (PR41101); NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358420 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 5 months ago
1 changed file(s) with 162 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
288288 ret i8 %r
289289 }
290290
291 ; https://bugs.llvm.org/show_bug.cgi?id=41101
292 ; TODO: Detect equivalence of selects with commuted operands: 'not' cond.
293
294 define i32 @select_not_cond(i1 %cond, i32 %t, i32 %f) {
295 ; CHECK-LABEL: @select_not_cond(
296 ; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[COND:%.*]], true
297 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[T:%.*]], i32 [[F:%.*]]
298 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[NOT]], i32 [[F]], i32 [[T]]
299 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
300 ; CHECK-NEXT: ret i32 [[R]]
301 ;
302 %not = xor i1 %cond, -1
303 %m1 = select i1 %cond, i32 %t, i32 %f
304 %m2 = select i1 %not, i32 %f, i32 %t
305 %r = xor i32 %m2, %m1
306 ret i32 %r
307 }
308
309 ; TODO: Detect equivalence of selects with commuted operands: 'not' cond with vector select.
310
311 define <2 x double> @select_not_cond_commute_vec(<2 x i1> %cond, <2 x double> %t, <2 x double> %f) {
312 ; CHECK-LABEL: @select_not_cond_commute_vec(
313 ; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[COND:%.*]],
314 ; CHECK-NEXT: [[M1:%.*]] = select <2 x i1> [[COND]], <2 x double> [[T:%.*]], <2 x double> [[F:%.*]]
315 ; CHECK-NEXT: [[M2:%.*]] = select <2 x i1> [[NOT]], <2 x double> [[F]], <2 x double> [[T]]
316 ; CHECK-NEXT: [[R:%.*]] = fdiv nnan <2 x double> [[M1]], [[M2]]
317 ; CHECK-NEXT: ret <2 x double> [[R]]
318 ;
319 %not = xor <2 x i1> %cond,
320 %m1 = select <2 x i1> %cond, <2 x double> %t, <2 x double> %f
321 %m2 = select <2 x i1> %not, <2 x double> %f, <2 x double> %t
322 %r = fdiv nnan <2 x double> %m1, %m2
323 ret <2 x double> %r
324 }
325
326 ; Negative test - select ops must be commuted.
327
328 define i32 @select_not_cond_wrong_select_ops(i1 %cond, i32 %t, i32 %f) {
329 ; CHECK-LABEL: @select_not_cond_wrong_select_ops(
330 ; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[COND:%.*]], true
331 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[T:%.*]], i32 [[F:%.*]]
332 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[NOT]], i32 [[T]], i32 [[F]]
333 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
334 ; CHECK-NEXT: ret i32 [[R]]
335 ;
336 %not = xor i1 %cond, -1
337 %m1 = select i1 %cond, i32 %t, i32 %f
338 %m2 = select i1 %not, i32 %t, i32 %f
339 %r = xor i32 %m2, %m1
340 ret i32 %r
341 }
342
343 ; Negative test - not a 'not'.
344
345 define i32 @select_not_cond_wrong_cond(i1 %cond, i32 %t, i32 %f) {
346 ; CHECK-LABEL: @select_not_cond_wrong_cond(
347 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND:%.*]], i32 [[T:%.*]], i32 [[F:%.*]]
348 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[COND]], i32 [[F]], i32 [[T]]
349 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
350 ; CHECK-NEXT: ret i32 [[R]]
351 ;
352 %not = xor i1 %cond, -2
353 %m1 = select i1 %cond, i32 %t, i32 %f
354 %m2 = select i1 %not, i32 %f, i32 %t
355 %r = xor i32 %m2, %m1
356 ret i32 %r
357 }
358
359 ; TODO: Detect equivalence of selects with commuted operands: inverted pred with fcmps.
360
361 define i32 @select_invert_pred_cond(float %x, i32 %t, i32 %f) {
362 ; CHECK-LABEL: @select_invert_pred_cond(
363 ; CHECK-NEXT: [[COND:%.*]] = fcmp ueq float [[X:%.*]], 4.200000e+01
364 ; CHECK-NEXT: [[INVCOND:%.*]] = fcmp one float [[X]], 4.200000e+01
365 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[T:%.*]], i32 [[F:%.*]]
366 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[INVCOND]], i32 [[F]], i32 [[T]]
367 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
368 ; CHECK-NEXT: ret i32 [[R]]
369 ;
370 %cond = fcmp ueq float %x, 42.0
371 %invcond = fcmp one float %x, 42.0
372 %m1 = select i1 %cond, i32 %t, i32 %f
373 %m2 = select i1 %invcond, i32 %f, i32 %t
374 %r = xor i32 %m2, %m1
375 ret i32 %r
376 }
377
378 ; TODO: Detect equivalence of selects with commuted operands: inverted pred with icmps and vectors.
379
380 define <2 x i32> @select_invert_pred_cond_commute_vec(<2 x i8> %x, <2 x i32> %t, <2 x i32> %f) {
381 ; CHECK-LABEL: @select_invert_pred_cond_commute_vec(
382 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt <2 x i8> [[X:%.*]],
383 ; CHECK-NEXT: [[INVCOND:%.*]] = icmp sle <2 x i8> [[X]],
384 ; CHECK-NEXT: [[M1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[T:%.*]], <2 x i32> [[F:%.*]]
385 ; CHECK-NEXT: [[M2:%.*]] = select <2 x i1> [[INVCOND]], <2 x i32> [[F]], <2 x i32> [[T]]
386 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[M1]], [[M2]]
387 ; CHECK-NEXT: ret <2 x i32> [[R]]
388 ;
389 %cond = icmp sgt <2 x i8> %x,
390 %invcond = icmp sle <2 x i8> %x,
391 %m1 = select <2 x i1> %cond, <2 x i32> %t, <2 x i32> %f
392 %m2 = select <2 x i1> %invcond, <2 x i32> %f, <2 x i32> %t
393 %r = xor <2 x i32> %m1, %m2
394 ret <2 x i32> %r
395 }
396
397 ; Negative test - select ops must be commuted.
398
399 define i32 @select_invert_pred_wrong_select_ops(float %x, i32 %t, i32 %f) {
400 ; CHECK-LABEL: @select_invert_pred_wrong_select_ops(
401 ; CHECK-NEXT: [[COND:%.*]] = fcmp ueq float [[X:%.*]], 4.200000e+01
402 ; CHECK-NEXT: [[INVCOND:%.*]] = fcmp one float [[X]], 4.200000e+01
403 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[F:%.*]], i32 [[T:%.*]]
404 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[INVCOND]], i32 [[F]], i32 [[T]]
405 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
406 ; CHECK-NEXT: ret i32 [[R]]
407 ;
408 %cond = fcmp ueq float %x, 42.0
409 %invcond = fcmp one float %x, 42.0
410 %m1 = select i1 %cond, i32 %f, i32 %t
411 %m2 = select i1 %invcond, i32 %f, i32 %t
412 %r = xor i32 %m2, %m1
413 ret i32 %r
414 }
415
416 ; Negative test - not an inverted predicate.
417
418 define i32 @select_invert_pred_wrong_cond(float %x, i32 %t, i32 %f) {
419 ; CHECK-LABEL: @select_invert_pred_wrong_cond(
420 ; CHECK-NEXT: [[COND:%.*]] = fcmp ueq float [[X:%.*]], 4.200000e+01
421 ; CHECK-NEXT: [[INVCOND:%.*]] = fcmp une float [[X]], 4.200000e+01
422 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[T:%.*]], i32 [[F:%.*]]
423 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[INVCOND]], i32 [[F]], i32 [[T]]
424 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
425 ; CHECK-NEXT: ret i32 [[R]]
426 ;
427 %cond = fcmp ueq float %x, 42.0
428 %invcond = fcmp une float %x, 42.0
429 %m1 = select i1 %cond, i32 %t, i32 %f
430 %m2 = select i1 %invcond, i32 %f, i32 %t
431 %r = xor i32 %m2, %m1
432 ret i32 %r
433 }
434
435 ; Negative test - cmp ops must match.
436
437 define i32 @select_invert_pred_wrong_cmp_ops(float %x, i32 %t, i32 %f) {
438 ; CHECK-LABEL: @select_invert_pred_wrong_cmp_ops(
439 ; CHECK-NEXT: [[COND:%.*]] = fcmp ueq float [[X:%.*]], 4.200000e+01
440 ; CHECK-NEXT: [[INVCOND:%.*]] = fcmp one float [[X]], 4.300000e+01
441 ; CHECK-NEXT: [[M1:%.*]] = select i1 [[COND]], i32 [[T:%.*]], i32 [[F:%.*]]
442 ; CHECK-NEXT: [[M2:%.*]] = select i1 [[INVCOND]], i32 [[F]], i32 [[T]]
443 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[M2]], [[M1]]
444 ; CHECK-NEXT: ret i32 [[R]]
445 ;
446 %cond = fcmp ueq float %x, 42.0
447 %invcond = fcmp one float %x, 43.0
448 %m1 = select i1 %cond, i32 %t, i32 %f
449 %m2 = select i1 %invcond, i32 %f, i32 %t
450 %r = xor i32 %m2, %m1
451 ret i32 %r
452 }