@@ -359,3 +359,143 @@ define i1 @test_icmp_sgt_and_negpow2_invalid_c(i32 %add) {
359359 %cmp = icmp sgt i32 %and , 48
360360 ret i1 %cmp
361361}
362+
363+ define i1 @icmp_eq_or_of_selects_with_constant (i1 %a , i1 %b ) {
364+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant(
365+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i64 65536, i64 0
366+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i64 256, i64 0
367+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i64 [[S1]], [[S2]]
368+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 65792
369+ ; CHECK-NEXT: ret i1 [[CMP]]
370+ ;
371+ %s1 = select i1 %a , i64 65536 , i64 0
372+ %s2 = select i1 %b , i64 256 , i64 0
373+ %or = or i64 %s1 , %s2
374+ %cmp = icmp eq i64 %or , 65792
375+ ret i1 %cmp
376+ }
377+
378+ define i1 @icmp_slt_and_of_selects_with_constant (i1 %a , i1 %b ) {
379+ ; CHECK-LABEL: @icmp_slt_and_of_selects_with_constant(
380+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i8 1, i8 -4
381+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i8 1, i8 -3
382+ ; CHECK-NEXT: [[AND:%.*]] = and i8 [[S1]], [[S2]]
383+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -2
384+ ; CHECK-NEXT: ret i1 [[CMP]]
385+ ;
386+ %s1 = select i1 %a , i8 1 , i8 254
387+ %s2 = select i1 %b , i8 1 , i8 253
388+ %and = and i8 %s1 , %s2
389+ %cmp = icmp slt i8 %and , 254
390+ ret i1 %cmp
391+ }
392+
393+ define i1 @icmp_sge_add_of_selects_with_constant (i1 %a , i1 %b ) {
394+ ; CHECK-LABEL: @icmp_sge_add_of_selects_with_constant(
395+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i8 -8, i8 7
396+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i8 16, i8 0
397+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[S1]], [[S2]]
398+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[ADD]], -10
399+ ; CHECK-NEXT: ret i1 [[CMP]]
400+ ;
401+ %s1 = select i1 %a , i8 248 , i8 7
402+ %s2 = select i1 %b , i8 16 , i8 0
403+ %add = add i8 %s1 , %s2
404+ %cmp = icmp sge i8 %add , 247
405+ ret i1 %cmp
406+ }
407+
408+ define i1 @icmp_eq_or_of_selects_with_constant_multiuse_foldable (i1 %a , i1 %b ) {
409+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant_multiuse_foldable(
410+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i64 65536, i64 0
411+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i64 256, i64 0
412+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i64 [[S1]], [[S2]]
413+ ; CHECK-NEXT: call void @use64(i64 [[OR]])
414+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 65792
415+ ; CHECK-NEXT: ret i1 [[CMP]]
416+ ;
417+ %s1 = select i1 %a , i64 65536 , i64 0
418+ %s2 = select i1 %b , i64 256 , i64 0
419+ %or = or i64 %s1 , %s2
420+ call void @use64 (i64 %or )
421+ %cmp = icmp eq i64 %or , 65792
422+ ret i1 %cmp
423+ }
424+
425+ define <2 x i1 > @icmp_eq_or_of_selects_with_constant_vectorized (<2 x i1 > %a , <2 x i1 > %b ) {
426+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant_vectorized(
427+ ; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> splat (i64 65536), <2 x i64> zeroinitializer
428+ ; CHECK-NEXT: [[S2:%.*]] = select <2 x i1> [[B:%.*]], <2 x i64> splat (i64 256), <2 x i64> zeroinitializer
429+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i64> [[S1]], [[S2]]
430+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[OR]], splat (i64 65792)
431+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
432+ ;
433+ %s1 = select <2 x i1 > %a , <2 x i64 > <i64 65536 , i64 65536 >, <2 x i64 > zeroinitializer
434+ %s2 = select <2 x i1 > %b , <2 x i64 > <i64 256 , i64 256 >, <2 x i64 > zeroinitializer
435+ %or = or <2 x i64 > %s1 , %s2
436+ %cmp = icmp eq <2 x i64 > %or , <i64 65792 , i64 65792 >
437+ ret <2 x i1 > %cmp
438+ }
439+
440+ define <2 x i1 > @icmp_eq_or_of_selects_with_scalar_cond_constant_vectorized (i1 %a , i1 %b ) {
441+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_scalar_cond_constant_vectorized(
442+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], <2 x i64> splat (i64 65536), <2 x i64> zeroinitializer
443+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], <2 x i64> splat (i64 256), <2 x i64> zeroinitializer
444+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i64> [[S1]], [[S2]]
445+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[OR]], splat (i64 65792)
446+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
447+ ;
448+ %s1 = select i1 %a , <2 x i64 > <i64 65536 , i64 65536 >, <2 x i64 > zeroinitializer
449+ %s2 = select i1 %b , <2 x i64 > <i64 256 , i64 256 >, <2 x i64 > zeroinitializer
450+ %or = or <2 x i64 > %s1 , %s2
451+ %cmp = icmp eq <2 x i64 > %or , <i64 65792 , i64 65792 >
452+ ret <2 x i1 > %cmp
453+ }
454+
455+ ; Negative tests.
456+ define i1 @icmp_eq_or_of_selects_with_constant_and_arg (i1 %a , i1 %b , i64 %arg ) {
457+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant_and_arg(
458+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i64 65536, i64 [[ARG:%.*]]
459+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i64 256, i64 0
460+ ; CHECK-NEXT: [[OR:%.*]] = or i64 [[S1]], [[S2]]
461+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 65792
462+ ; CHECK-NEXT: ret i1 [[CMP]]
463+ ;
464+ %s1 = select i1 %a , i64 65536 , i64 %arg
465+ %s2 = select i1 %b , i64 256 , i64 0
466+ %or = or i64 %s1 , %s2
467+ %cmp = icmp eq i64 %or , 65792
468+ ret i1 %cmp
469+ }
470+
471+ define i1 @icmp_eq_or_of_selects_with_constant_multiuse (i1 %a , i1 %b ) {
472+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant_multiuse(
473+ ; CHECK-NEXT: [[S1:%.*]] = select i1 [[A:%.*]], i64 0, i64 65536
474+ ; CHECK-NEXT: [[S2:%.*]] = select i1 [[B:%.*]], i64 0, i64 256
475+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i64 [[S1]], [[S2]]
476+ ; CHECK-NEXT: call void @use64(i64 [[OR]])
477+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 65792
478+ ; CHECK-NEXT: ret i1 [[CMP]]
479+ ;
480+ %s1 = select i1 %a , i64 0 , i64 65536
481+ %s2 = select i1 %b , i64 0 , i64 256
482+ %or = or i64 %s1 , %s2
483+ call void @use64 (i64 %or )
484+ %cmp = icmp eq i64 %or , 65792
485+ ret i1 %cmp
486+ }
487+
488+ define <2 x i1 > @icmp_eq_or_of_selects_with_constant_vectorized_nonsplat (<2 x i1 > %a , <2 x i1 > %b ) {
489+ ; CHECK-LABEL: @icmp_eq_or_of_selects_with_constant_vectorized_nonsplat(
490+ ; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> splat (i64 65536), <2 x i64> zeroinitializer
491+ ; CHECK-NEXT: [[S2:%.*]] = select <2 x i1> [[B:%.*]], <2 x i64> <i64 256, i64 128>, <2 x i64> zeroinitializer
492+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i64> [[S1]], [[S2]]
493+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[OR]], <i64 65792, i64 65664>
494+ ; CHECK-NEXT: ret <2 x i1> [[CMP]]
495+ ;
496+ %s1 = select <2 x i1 > %a , <2 x i64 > <i64 65536 , i64 65536 >, <2 x i64 > zeroinitializer
497+ %s2 = select <2 x i1 > %b , <2 x i64 > <i64 256 , i64 128 >, <2 x i64 > zeroinitializer
498+ %or = or <2 x i64 > %s1 , %s2
499+ %cmp = icmp eq <2 x i64 > %or , <i64 65792 , i64 65664 >
500+ ret <2 x i1 > %cmp
501+ }
0 commit comments