@@ -2661,3 +2661,139 @@ define i8 @sub_of_adds_2xc(i8 %x, i8 %y) {
26612661 %r = sub i8 %xc , %yc
26622662 ret i8 %r
26632663}
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