@@ -9,6 +9,7 @@ declare i8 @llvm.umax.i8(i8, i8)
9
9
declare void @llvm.assume (i1 )
10
10
11
11
declare void @use.i8 (i8 )
12
+ declare void @use.i1 (i1 )
12
13
13
14
define i8 @xor_1 (i8 %a , i1 %c , i8 %x , i8 %y ) {
14
15
; CHECK-LABEL: @xor_1(
@@ -544,11 +545,198 @@ define i8 @lshr_not_nneg(i8 %x, i8 %y) {
544
545
define i8 @lshr_not_nneg2 (i8 %x ) {
545
546
; CHECK-LABEL: @lshr_not_nneg2(
546
547
; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X:%.*]], 1
547
- ; CHECK-NEXT: [[SHR_NOT1 :%.*]] = or disjoint i8 [[SHR]], -128
548
- ; CHECK-NEXT: ret i8 [[SHR_NOT1 ]]
548
+ ; CHECK-NEXT: [[SHR_NOT :%.*]] = or disjoint i8 [[SHR]], -128
549
+ ; CHECK-NEXT: ret i8 [[SHR_NOT ]]
549
550
;
550
551
%x.not = xor i8 %x , -1
551
552
%shr = lshr i8 %x.not , 1
552
553
%shr.not = xor i8 %shr , -1
553
554
ret i8 %shr.not
554
555
}
556
+
557
+ define i1 @test_inv_free (i1 %c1 , i1 %c2 , i1 %c3 , i1 %c4 ) {
558
+ ; CHECK-LABEL: @test_inv_free(
559
+ ; CHECK-NEXT: entry:
560
+ ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
561
+ ; CHECK: b1:
562
+ ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
563
+ ; CHECK: b2:
564
+ ; CHECK-NEXT: br label [[EXIT]]
565
+ ; CHECK: b3:
566
+ ; CHECK-NEXT: br label [[EXIT]]
567
+ ; CHECK: exit:
568
+ ; CHECK-NEXT: [[VAL_NOT:%.*]] = phi i1 [ false, [[B1]] ], [ true, [[B2]] ], [ [[C3:%.*]], [[B3]] ]
569
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = and i1 [[VAL_NOT]], [[C4:%.*]]
570
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[B5:%.*]], label [[B4:%.*]]
571
+ ; CHECK: b4:
572
+ ; CHECK-NEXT: ret i1 true
573
+ ; CHECK: b5:
574
+ ; CHECK-NEXT: ret i1 false
575
+ ;
576
+ entry:
577
+ br i1 %c1 , label %b1 , label %b2
578
+ b1:
579
+ br i1 %c2 , label %exit , label %b3
580
+ b2:
581
+ br label %exit
582
+ b3:
583
+ %invc3 = xor i1 %c3 , true
584
+ br label %exit
585
+ exit:
586
+ %val = phi i1 [ true , %b1 ], [ false , %b2 ], [ %invc3 , %b3 ]
587
+ %inv = xor i1 %c4 , true
588
+ %cond = or i1 %val , %inv
589
+ br i1 %cond , label %b4 , label %b5
590
+ b4:
591
+ ret i1 true
592
+ b5:
593
+ ret i1 false
594
+ }
595
+
596
+ define i32 @test_inv_free_i32 (i1 %c1 , i1 %c2 , i32 %c3 , i32 %c4 ) {
597
+ ; CHECK-LABEL: @test_inv_free_i32(
598
+ ; CHECK-NEXT: entry:
599
+ ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
600
+ ; CHECK: b1:
601
+ ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
602
+ ; CHECK: b2:
603
+ ; CHECK-NEXT: br label [[EXIT]]
604
+ ; CHECK: b3:
605
+ ; CHECK-NEXT: br label [[EXIT]]
606
+ ; CHECK: exit:
607
+ ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[B1]] ], [ -1, [[B2]] ], [ [[C3:%.*]], [[B3]] ]
608
+ ; CHECK-NEXT: [[COND:%.*]] = xor i32 [[TMP0]], [[C4:%.*]]
609
+ ; CHECK-NEXT: ret i32 [[COND]]
610
+ ;
611
+ entry:
612
+ br i1 %c1 , label %b1 , label %b2
613
+ b1:
614
+ br i1 %c2 , label %exit , label %b3
615
+ b2:
616
+ br label %exit
617
+ b3:
618
+ %invc3 = xor i32 %c3 , -1
619
+ br label %exit
620
+ exit:
621
+ %val = phi i32 [ -1 , %b1 ], [ 0 , %b2 ], [ %invc3 , %b3 ]
622
+ %inv = xor i32 %c4 , -1
623
+ %cond = xor i32 %val , %inv
624
+ ret i32 %cond
625
+ }
626
+
627
+ ; Negative tests
628
+
629
+ define i1 @test_inv_free_multiuse (i1 %c1 , i1 %c2 , i1 %c3 , i1 %c4 ) {
630
+ ; CHECK-LABEL: @test_inv_free_multiuse(
631
+ ; CHECK-NEXT: entry:
632
+ ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
633
+ ; CHECK: b1:
634
+ ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
635
+ ; CHECK: b2:
636
+ ; CHECK-NEXT: br label [[EXIT]]
637
+ ; CHECK: b3:
638
+ ; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
639
+ ; CHECK-NEXT: br label [[EXIT]]
640
+ ; CHECK: exit:
641
+ ; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ]
642
+ ; CHECK-NEXT: call void @use.i1(i1 [[VAL]])
643
+ ; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true
644
+ ; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]
645
+ ; CHECK-NEXT: br i1 [[COND]], label [[B4:%.*]], label [[B5:%.*]]
646
+ ; CHECK: b4:
647
+ ; CHECK-NEXT: ret i1 true
648
+ ; CHECK: b5:
649
+ ; CHECK-NEXT: ret i1 false
650
+ ;
651
+ entry:
652
+ br i1 %c1 , label %b1 , label %b2
653
+ b1:
654
+ br i1 %c2 , label %exit , label %b3
655
+ b2:
656
+ br label %exit
657
+ b3:
658
+ %invc3 = xor i1 %c3 , true
659
+ br label %exit
660
+ exit:
661
+ %val = phi i1 [ true , %b1 ], [ false , %b2 ], [ %invc3 , %b3 ]
662
+ call void @use.i1 (i1 %val )
663
+ %inv = xor i1 %c4 , true
664
+ %cond = or i1 %val , %inv
665
+ br i1 %cond , label %b4 , label %b5
666
+ b4:
667
+ ret i1 true
668
+ b5:
669
+ ret i1 false
670
+ }
671
+
672
+ define i32 @test_inv_free_i32_newinst (i1 %c1 , i1 %c2 , i32 %c3 , i32 %c4 ) {
673
+ ; CHECK-LABEL: @test_inv_free_i32_newinst(
674
+ ; CHECK-NEXT: entry:
675
+ ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
676
+ ; CHECK: b1:
677
+ ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
678
+ ; CHECK: b2:
679
+ ; CHECK-NEXT: br label [[EXIT]]
680
+ ; CHECK: b3:
681
+ ; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 -8, [[C3:%.*]]
682
+ ; CHECK-NEXT: br label [[EXIT]]
683
+ ; CHECK: exit:
684
+ ; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ -1, [[B1]] ], [ 0, [[B2]] ], [ [[ASHR]], [[B3]] ]
685
+ ; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[VAL]], [[C4:%.*]]
686
+ ; CHECK-NEXT: [[COND:%.*]] = xor i32 [[TMP0]], -1
687
+ ; CHECK-NEXT: ret i32 [[COND]]
688
+ ;
689
+ entry:
690
+ br i1 %c1 , label %b1 , label %b2
691
+ b1:
692
+ br i1 %c2 , label %exit , label %b3
693
+ b2:
694
+ br label %exit
695
+ b3:
696
+ %ashr = ashr i32 -8 , %c3
697
+ br label %exit
698
+ exit:
699
+ %val = phi i32 [ -1 , %b1 ], [ 0 , %b2 ], [ %ashr , %b3 ]
700
+ %inv = xor i32 %c4 , -1
701
+ %cond = xor i32 %val , %inv
702
+ ret i32 %cond
703
+ }
704
+
705
+ define i1 @test_inv_free_loop (i1 %c1 , i1 %c2 , i1 %c3 , i1 %c4 ) {
706
+ ; CHECK-LABEL: @test_inv_free_loop(
707
+ ; CHECK-NEXT: entry:
708
+ ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
709
+ ; CHECK: b1:
710
+ ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
711
+ ; CHECK: b2:
712
+ ; CHECK-NEXT: br label [[EXIT]]
713
+ ; CHECK: b3:
714
+ ; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
715
+ ; CHECK-NEXT: br label [[EXIT]]
716
+ ; CHECK: exit:
717
+ ; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ], [ [[NOT:%.*]], [[EXIT]] ]
718
+ ; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true
719
+ ; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]
720
+ ; CHECK-NEXT: [[NOT]] = xor i1 [[VAL]], true
721
+ ; CHECK-NEXT: br i1 [[COND]], label [[EXIT]], label [[B4:%.*]]
722
+ ; CHECK: b4:
723
+ ; CHECK-NEXT: ret i1 true
724
+ ;
725
+ entry:
726
+ br i1 %c1 , label %b1 , label %b2
727
+ b1:
728
+ br i1 %c2 , label %exit , label %b3
729
+ b2:
730
+ br label %exit
731
+ b3:
732
+ %invc3 = xor i1 %c3 , true
733
+ br label %exit
734
+ exit:
735
+ %val = phi i1 [ true , %b1 ], [ false , %b2 ], [ %invc3 , %b3 ], [ %not , %exit ]
736
+ %inv = xor i1 %c4 , true
737
+ %cond = or i1 %val , %inv
738
+ %not = xor i1 %val , true
739
+ br i1 %cond , label %exit , label %b4
740
+ b4:
741
+ ret i1 true
742
+ }
0 commit comments