@@ -2661,3 +2661,139 @@ define i8 @sub_of_adds_2xc(i8 %x, i8 %y) {
2661
2661
%r = sub i8 %xc , %yc
2662
2662
ret i8 %r
2663
2663
}
2664
+
2665
+ define i32 @sub_infer_nuw_from_domcond (i32 %x , i32 %y ) {
2666
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond(
2667
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2668
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
2669
+ ; CHECK: if.then:
2670
+ ; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[X]], [[Y]]
2671
+ ; CHECK-NEXT: ret i32 [[SUB]]
2672
+ ; CHECK: if.else:
2673
+ ; CHECK-NEXT: ret i32 0
2674
+ ;
2675
+ %cond = icmp uge i32 %x , %y
2676
+ br i1 %cond , label %if.then , label %if.else
2677
+
2678
+ if.then:
2679
+ %sub = sub i32 %x , %y
2680
+ ret i32 %sub
2681
+
2682
+ if.else:
2683
+ ret i32 0
2684
+ }
2685
+
2686
+ define i1 @sub_infer_nuw_from_domcond_fold1 (i32 %x , i32 %y ) {
2687
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold1(
2688
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2689
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
2690
+ ; CHECK: if.then:
2691
+ ; CHECK-NEXT: ret i1 false
2692
+ ; CHECK: if.else:
2693
+ ; CHECK-NEXT: ret i1 false
2694
+ ;
2695
+ %cond = icmp uge i32 %x , %y
2696
+ br i1 %cond , label %if.then , label %if.else
2697
+
2698
+ if.then:
2699
+ %ext0 = zext i32 %y to i64
2700
+ %ext1 = zext i32 %x to i64
2701
+ %sub = sub i32 %x , %y
2702
+ %ext2 = zext i32 %sub to i64
2703
+ %add = add nuw nsw i64 %ext2 , %ext0
2704
+ %cmp = icmp ugt i64 %add , %ext1
2705
+ ret i1 %cmp
2706
+
2707
+ if.else:
2708
+ ret i1 false
2709
+ }
2710
+
2711
+ define i64 @sub_infer_nuw_from_domcond_fold2 (i32 range(i32 0 , 2147483648 ) %x , i32 range(i32 0 , 2147483648 ) %y ) {
2712
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold2(
2713
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2714
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
2715
+ ; CHECK: if.then:
2716
+ ; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[X]], [[Y]]
2717
+ ; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[SUB]] to i64
2718
+ ; CHECK-NEXT: ret i64 [[EXT]]
2719
+ ; CHECK: if.else:
2720
+ ; CHECK-NEXT: ret i64 0
2721
+ ;
2722
+ %cond = icmp uge i32 %x , %y
2723
+ br i1 %cond , label %if.then , label %if.else
2724
+
2725
+ if.then:
2726
+ %sub = sub i32 %x , %y
2727
+ %ext = zext i32 %sub to i64
2728
+ ret i64 %ext
2729
+
2730
+ if.else:
2731
+ ret i64 0
2732
+ }
2733
+
2734
+ define i1 @sub_infer_nuw_from_domcond_fold3 (i16 %xx , i32 range(i32 0 , 12 ) %y ) {
2735
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold3(
2736
+ ; CHECK-NEXT: [[X:%.*]] = zext i16 [[XX:%.*]] to i32
2737
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
2738
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
2739
+ ; CHECK: if.then:
2740
+ ; CHECK-NEXT: ret i1 false
2741
+ ; CHECK: if.else:
2742
+ ; CHECK-NEXT: ret i1 false
2743
+ ;
2744
+ %x = zext i16 %xx to i32
2745
+ %cond = icmp ult i32 %x , %y
2746
+ br i1 %cond , label %if.then , label %if.else
2747
+
2748
+ if.then:
2749
+ %sub = sub nsw i32 %y , %x
2750
+ %cmp = icmp eq i32 %sub , -1
2751
+ ret i1 %cmp
2752
+
2753
+ if.else:
2754
+ ret i1 false
2755
+ }
2756
+
2757
+ ; negative tests
2758
+
2759
+ define i32 @sub_infer_nuw_from_domcond_wrong_pred (i32 %x , i32 %y ) {
2760
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond_wrong_pred(
2761
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
2762
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
2763
+ ; CHECK: if.then:
2764
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2765
+ ; CHECK-NEXT: ret i32 [[SUB]]
2766
+ ; CHECK: if.else:
2767
+ ; CHECK-NEXT: ret i32 0
2768
+ ;
2769
+ %cond = icmp sge i32 %x , %y
2770
+ br i1 %cond , label %if.then , label %if.else
2771
+
2772
+ if.then:
2773
+ %sub = sub i32 %x , %y
2774
+ ret i32 %sub
2775
+
2776
+ if.else:
2777
+ ret i32 0
2778
+ }
2779
+
2780
+ define i32 @sub_infer_nuw_from_domcond_lhs_is_false (i32 %x , i32 %y ) {
2781
+ ; CHECK-LABEL: @sub_infer_nuw_from_domcond_lhs_is_false(
2782
+ ; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2783
+ ; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
2784
+ ; CHECK: if.then:
2785
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2786
+ ; CHECK-NEXT: ret i32 [[SUB]]
2787
+ ; CHECK: if.else:
2788
+ ; CHECK-NEXT: ret i32 0
2789
+ ;
2790
+ %cond = icmp uge i32 %x , %y
2791
+ br i1 %cond , label %if.else , label %if.then
2792
+
2793
+ if.then:
2794
+ %sub = sub i32 %x , %y
2795
+ ret i32 %sub
2796
+
2797
+ if.else:
2798
+ ret i32 0
2799
+ }
0 commit comments