@@ -534,3 +534,215 @@ 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: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
573+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
574+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
575+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
576+ ; CHECK-NEXT: ret i1 [[CMP]]
577+ ; CHECK: if.end:
578+ ; CHECK-NEXT: ret i1 false
579+ ;
580+ entry:
581+ %cond1 = icmp eq i64 %y , %x
582+ %cond2 = icmp eq i64 %w , %z
583+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
584+ br i1 %or.cond , label %if.end , label %if.then
585+
586+ if.then:
587+ %sub1 = sub i64 %w , %z
588+ %sub2 = sub i64 %y , %x
589+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
590+ %cmp = icmp eq i64 %umin , 0
591+ ret i1 %cmp
592+
593+ if.end:
594+ ret i1 false
595+ }
596+
597+ define i1 @test_nonequal_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
598+ ; CHECK-LABEL: @test_nonequal_domcond2(
599+ ; CHECK-NEXT: entry:
600+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
601+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
602+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false
603+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
604+ ; CHECK: if.then:
605+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
606+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
607+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
608+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
609+ ; CHECK-NEXT: ret i1 [[CMP]]
610+ ; CHECK: if.end:
611+ ; CHECK-NEXT: ret i1 false
612+ ;
613+ entry:
614+ %cond1 = icmp ne i64 %y , %x
615+ %cond2 = icmp ne i64 %w , %z
616+ %or.cond = select i1 %cond1 , i1 %cond2 , i1 false
617+ br i1 %or.cond , label %if.then , label %if.end
618+
619+ if.then:
620+ %sub1 = sub i64 %w , %z
621+ %sub2 = sub i64 %y , %x
622+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
623+ %cmp = icmp eq i64 %umin , 0
624+ ret i1 %cmp
625+
626+ if.end:
627+ ret i1 false
628+ }
629+
630+ define i1 @test_nonequal_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
631+ ; CHECK-LABEL: @test_nonequal_assume(
632+ ; CHECK-NEXT: entry:
633+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
634+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
635+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
636+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
637+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
638+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
639+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
640+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
641+ ; CHECK-NEXT: ret i1 [[CMP]]
642+ ;
643+ entry:
644+ %cond1 = icmp ne i64 %y , %x
645+ call void @llvm.assume (i1 %cond1 )
646+ %cond2 = icmp ne i64 %w , %z
647+ call void @llvm.assume (i1 %cond2 )
648+
649+ %sub1 = sub i64 %w , %z
650+ %sub2 = sub i64 %y , %x
651+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
652+ %cmp = icmp eq i64 %umin , 0
653+ ret i1 %cmp
654+ }
655+
656+ ; Negative tests
657+
658+ define i1 @test_nonequal_invalid_domcond1 (i64 %x , i64 %y , i64 %z , i64 %w ) {
659+ ; CHECK-LABEL: @test_nonequal_invalid_domcond1(
660+ ; CHECK-NEXT: entry:
661+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y:%.*]], [[X:%.*]]
662+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
663+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
664+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
665+ ; CHECK: if.then:
666+ ; CHECK-NEXT: ret i1 true
667+ ; CHECK: if.end:
668+ ; CHECK-NEXT: ret i1 false
669+ ;
670+ entry:
671+ %cond1 = icmp ne i64 %y , %x
672+ %cond2 = icmp eq i64 %w , %z
673+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
674+ br i1 %or.cond , label %if.end , label %if.then
675+
676+ if.then:
677+ %sub1 = sub i64 %w , %z
678+ %sub2 = sub i64 %y , %x
679+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
680+ %cmp = icmp eq i64 %umin , 0
681+ ret i1 %cmp
682+
683+ if.end:
684+ ret i1 false
685+ }
686+
687+ define i1 @test_nonequal_invalid_domcond2 (i64 %x , i64 %y , i64 %z , i64 %w ) {
688+ ; CHECK-LABEL: @test_nonequal_invalid_domcond2(
689+ ; CHECK-NEXT: entry:
690+ ; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
691+ ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[W:%.*]], [[Z:%.*]]
692+ ; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
693+ ; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
694+ ; CHECK: if.then:
695+ ; CHECK-NEXT: br label [[IF_END]]
696+ ; CHECK: if.end:
697+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
698+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
699+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
700+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
701+ ; CHECK-NEXT: ret i1 [[CMP]]
702+ ;
703+ entry:
704+ %cond1 = icmp eq i64 %y , %x
705+ %cond2 = icmp eq i64 %w , %z
706+ %or.cond = select i1 %cond1 , i1 true , i1 %cond2
707+ br i1 %or.cond , label %if.then , label %if.end
708+
709+ if.then:
710+ br label %if.end
711+
712+ if.end:
713+ %sub1 = sub i64 %w , %z
714+ %sub2 = sub i64 %y , %x
715+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
716+ %cmp = icmp eq i64 %umin , 0
717+ ret i1 %cmp
718+ }
719+
720+ define i1 @test_nonequal_invalid_assume (i64 %x , i64 %y , i64 %z , i64 %w ) {
721+ ; CHECK-LABEL: @test_nonequal_invalid_assume(
722+ ; CHECK-NEXT: entry:
723+ ; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W:%.*]], [[Z:%.*]]
724+ ; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y:%.*]], [[X:%.*]]
725+ ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
726+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
727+ ; CHECK-NEXT: call void @side_effect()
728+ ; CHECK-NEXT: [[COND1:%.*]] = icmp ne i64 [[Y]], [[X]]
729+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
730+ ; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W]], [[Z]]
731+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
732+ ; CHECK-NEXT: ret i1 [[CMP]]
733+ ;
734+ entry:
735+ %sub1 = sub i64 %w , %z
736+ %sub2 = sub i64 %y , %x
737+ %umin = call i64 @llvm.umin.i64 (i64 %sub1 , i64 %sub2 )
738+ %cmp = icmp eq i64 %umin , 0
739+
740+ call void @side_effect ()
741+ %cond1 = icmp ne i64 %y , %x
742+ call void @llvm.assume (i1 %cond1 )
743+ %cond2 = icmp ne i64 %w , %z
744+ call void @llvm.assume (i1 %cond2 )
745+ ret i1 %cmp
746+ }
747+
748+ declare void @side_effect ()
0 commit comments