@@ -534,3 +534,203 @@ else:
534534 %cmp1 = icmp eq i32 %and1 , 0
535535 ret i1 %cmp1
536536}
537+
538+ ; TODO: X != Y implies X | Y != 0
539+ define i1 @or_nonzero_from_nonequal (i8 %x , i8 %y ) {
540+ ; CHECK-LABEL: @or_nonzero_from_nonequal(
541+ ; CHECK-NEXT: entry:
542+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
543+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
544+ ; CHECK: if.then:
545+ ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[Y]]
546+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0
547+ ; CHECK-NEXT: ret i1 [[CMP]]
548+ ; CHECK: if.else:
549+ ; CHECK-NEXT: ret i1 false
550+ ;
551+ entry:
552+ %cond = icmp eq i8 %x , %y
553+ br i1 %cond , label %if.else , label %if.then
554+
555+ if.then:
556+ %or = or i8 %x , %y
557+ %cmp = icmp eq i8 %or , 0
558+ ret i1 %cmp
559+
560+ if.else:
561+ ret i1 false
562+ }
563+
564+ define i1 @test_nonequal_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
565+ ; CHECK-LABEL: @test_nonequal_domcond1(
566+ ; CHECK-NEXT: entry:
567+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
568+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
569+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
570+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
571+ ; CHECK: if.then:
572+ ; CHECK-NEXT: ret i1 false
573+ ; CHECK: if.end:
574+ ; CHECK-NEXT: ret i1 false
575+ ;
576+ entry:
577+ %cond1 = icmp eq i64 %y , %x
578+ %cond2 = icmp eq i64 %w , %z
579+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
580+ br i1 %or.cond , label %if.end , label %if.then
581+
582+ if.then:
583+ %sub1 = sub i64 %w , %z
584+ %sub2 = sub i64 %y , %x
585+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
586+ %cmp = icmp eq i64 %umin , 0
587+ ret i1 %cmp
588+
589+ if.end:
590+ ret i1 false
591+ }
592+
593+ define i1 @test_nonequal_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
594+ ; CHECK-LABEL: @test_nonequal_domcond2(
595+ ; CHECK-NEXT: entry:
596+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
597+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
598+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false
599+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
600+ ; CHECK: if.then:
601+ ; CHECK-NEXT: ret i1 false
602+ ; CHECK: if.end:
603+ ; CHECK-NEXT: ret i1 false
604+ ;
605+ entry:
606+ %cond1 = icmp ne i64 %y , %x
607+ %cond2 = icmp ne i64 %w , %z
608+ %or.cond = select i1 %cond1 , i1 %cond2 , i1 false
609+ br i1 %or.cond , label %if.then , label %if.end
610+
611+ if.then:
612+ %sub1 = sub i64 %w , %z
613+ %sub2 = sub i64 %y , %x
614+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
615+ %cmp = icmp eq i64 %umin , 0
616+ ret i1 %cmp
617+
618+ if.end:
619+ ret i1 false
620+ }
621+
622+ define i1 @test_nonequal_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
623+ ; CHECK-LABEL: @test_nonequal_assume(
624+ ; CHECK-NEXT: entry:
625+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
626+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
627+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
628+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
629+ ; CHECK-NEXT: ret i1 false
630+ ;
631+ entry:
632+ %cond1 = icmp ne i64 %y , %x
633+ call void @llvm.assume (i1 %cond1 )
634+ %cond2 = icmp ne i64 %w , %z
635+ call void @llvm.assume (i1 %cond2 )
636+
637+ %sub1 = sub i64 %w , %z
638+ %sub2 = sub i64 %y , %x
639+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
640+ %cmp = icmp eq i64 %umin , 0
641+ ret i1 %cmp
642+ }
643+
644+ ; Negative tests
645+
646+ define i1 @test_nonequal_invalid_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
647+ ; CHECK-LABEL: @test_nonequal_invalid_domcond1(
648+ ; CHECK-NEXT: entry:
649+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
650+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
651+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
652+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
653+ ; CHECK: if.then:
654+ ; CHECK-NEXT: ret i1 true
655+ ; CHECK: if.end:
656+ ; CHECK-NEXT: ret i1 false
657+ ;
658+ entry:
659+ %cond1 = icmp ne i64 %y , %x
660+ %cond2 = icmp eq i64 %w , %z
661+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
662+ br i1 %or.cond , label %if.end , label %if.then
663+
664+ if.then:
665+ %sub1 = sub i64 %w , %z
666+ %sub2 = sub i64 %y , %x
667+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
668+ %cmp = icmp eq i64 %umin , 0
669+ ret i1 %cmp
670+
671+ if.end:
672+ ret i1 false
673+ }
674+
675+ define i1 @test_nonequal_invalid_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
676+ ; CHECK-LABEL: @test_nonequal_invalid_domcond2(
677+ ; CHECK-NEXT: entry:
678+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
679+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
680+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
681+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
682+ ; CHECK: if.then:
683+ ; CHECK-NEXT: br label [[IF_END]]
684+ ; CHECK: if.end:
685+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
686+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
687+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
688+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
689+ ; CHECK-NEXT: ret i1 [[CMP]]
690+ ;
691+ entry:
692+ %cond1 = icmp eq i64 %y , %x
693+ %cond2 = icmp eq i64 %w , %z
694+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
695+ br i1 %or.cond , label %if.then , label %if.end
696+
697+ if.then:
698+ br label %if.end
699+
700+ if.end:
701+ %sub1 = sub i64 %w , %z
702+ %sub2 = sub i64 %y , %x
703+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
704+ %cmp = icmp eq i64 %umin , 0
705+ ret i1 %cmp
706+ }
707+
708+ define i1 @test_nonequal_invalid_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
709+ ; CHECK-LABEL: @test_nonequal_invalid_assume(
710+ ; CHECK-NEXT: entry:
711+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W:%.*]], [[Z:%.*]]
712+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y:%.*]], [[X:%.*]]
713+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
714+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
715+ ; CHECK-NEXT: call void @side_effect()
716+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y]], [[X]]
717+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
718+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W]], [[Z]]
719+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
720+ ; CHECK-NEXT: ret i1 [[CMP]]
721+ ;
722+ entry:
723+ %sub1 = sub i64 %w , %z
724+ %sub2 = sub i64 %y , %x
725+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
726+ %cmp = icmp eq i64 %umin , 0
727+
728+ call void @side_effect ()
729+ %cond1 = icmp ne i64 %y , %x
730+ call void @llvm.assume (i1 %cond1 )
731+ %cond2 = icmp ne i64 %w , %z
732+ call void @llvm.assume (i1 %cond2 )
733+ ret i1 %cmp
734+ }
735+
736+ declare void @side_effect ()
0 commit comments