|  | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | 
|  | ; RUN: opt < %s -passes=ipsccp -S | FileCheck %s | 
|  |  | 
|  | declare void @use(i1) | 
|  |  | 
|  | ; We can simplify the conditions in the true block, because the condition | 
|  | ; allows us to replace all uses of %a in the block with a  constant. | 
|  | define void @val_undef_eq() { | 
|  | ; CHECK-LABEL: @val_undef_eq( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[A:%.*]] = add i32 undef, 0 | 
|  | ; CHECK-NEXT:    [[BC_1:%.*]] = icmp eq i32 [[A]], 10 | 
|  | ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    call void @use(i1 false) | 
|  | ; CHECK-NEXT:    call void @use(i1 true) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       false: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %a = add i32 undef, 0 | 
|  | %bc.1 = icmp eq i32 %a, 10 | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp ne i32 %a, 10 | 
|  | call void @use(i1 %f.1) | 
|  | %f.2 = icmp eq i32 %a,  10 | 
|  | call void @use(i1 %f.2) | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare void @use.i32(i32) | 
|  |  | 
|  | ; It is not allowed to use the range information from the condition to remove | 
|  | ; %a.127 = and ... in the true block, as %a could be undef. | 
|  | define void @val_undef_range() { | 
|  | ; CHECK-LABEL: @val_undef_range( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[A:%.*]] = add i32 undef, 0 | 
|  | ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ult i32 [[A]], 127 | 
|  | ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    call void @use(i1 false) | 
|  | ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A]], 127 | 
|  | ; CHECK-NEXT:    call void @use.i32(i32 [[A_127]]) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       false: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %a = add i32 undef, 0 | 
|  | %bc.1 = icmp ult i32 %a, 127 | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp eq i32 %a, 128 | 
|  | call void @use(i1 %f.1) | 
|  |  | 
|  | %a.127 = and i32 %a, 127 | 
|  | call void @use.i32(i32 %a.127) | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; All uses of %p can be replaced by a constant (10). | 
|  | define void @val_singlecrfromundef_range(i1 %cond) { | 
|  | ; CHECK-LABEL: @val_singlecrfromundef_range( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]] | 
|  | ; CHECK:       inc1: | 
|  | ; CHECK-NEXT:    br label [[IF:%.*]] | 
|  | ; CHECK:       inc2: | 
|  | ; CHECK-NEXT:    br label [[IF]] | 
|  | ; CHECK:       if: | 
|  | ; CHECK-NEXT:    br label [[TRUE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    call void @use(i1 false) | 
|  | ; CHECK-NEXT:    [[P_127:%.*]] = and i32 10, 127 | 
|  | ; CHECK-NEXT:    call void @use.i32(i32 [[P_127]]) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  |  | 
|  | br i1 %cond, label %inc1, label %inc2 | 
|  |  | 
|  | inc1: | 
|  | br label %if | 
|  |  | 
|  | inc2: | 
|  | br label %if | 
|  |  | 
|  | if: | 
|  | %p = phi i32 [ 10, %inc1 ], [ undef, %inc2 ] | 
|  | %bc.1 = icmp ult i32 %p, 127 | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp eq i32 %p, 128 | 
|  | call void @use(i1 %f.1) | 
|  |  | 
|  | %p.127 = and i32 %p, 127 | 
|  | call void @use.i32(i32 %p.127) | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } | 
|  |  | 
|  |  | 
|  | ; It is not allowed to use the information from the condition ([0, 128)) | 
|  | ; to remove a.127.2 = and i32 %p, 127, as %p might be undef. | 
|  | define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) { | 
|  | ; CHECK-LABEL: @val_undef_to_cr_to_overdef_range( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A:%.*]], 127 | 
|  | ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]] | 
|  | ; CHECK:       inc1: | 
|  | ; CHECK-NEXT:    br label [[IF:%.*]] | 
|  | ; CHECK:       inc2: | 
|  | ; CHECK-NEXT:    br label [[IF]] | 
|  | ; CHECK:       if: | 
|  | ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[A_127]], [[INC1]] ], [ undef, [[INC2]] ] | 
|  | ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ult i32 [[P]], 100 | 
|  | ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    call void @use(i1 false) | 
|  | ; CHECK-NEXT:    [[P_127:%.*]] = and i32 [[P]], 127 | 
|  | ; CHECK-NEXT:    call void @use.i32(i32 [[P_127]]) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       false: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %a.127 = and i32 %a, 127 | 
|  | br i1 %cond, label %inc1, label %inc2 | 
|  |  | 
|  | inc1: | 
|  | br label %if | 
|  |  | 
|  | inc2: | 
|  | br label %if | 
|  |  | 
|  | if: | 
|  | %p = phi i32 [ %a.127, %inc1 ], [ undef, %inc2 ] | 
|  | %bc.1 = icmp ult i32 %p, 100 | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp eq i32 %p, 128 | 
|  | call void @use(i1 %f.1) | 
|  |  | 
|  | %p.127 = and i32 %p, 127 | 
|  | call void @use.i32(i32 %p.127) | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; All uses of %p can be replaced by a constant (10), we are allowed to use it | 
|  | ; as a bound too. | 
|  | define void @bound_singlecrfromundef(i32 %a, i1 %cond) { | 
|  | ; CHECK-LABEL: @bound_singlecrfromundef( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] | 
|  | ; CHECK:       bb1: | 
|  | ; CHECK-NEXT:    br label [[PRED:%.*]] | 
|  | ; CHECK:       bb2: | 
|  | ; CHECK-NEXT:    br label [[PRED]] | 
|  | ; CHECK:       pred: | 
|  | ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10 | 
|  | ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    call void @use(i1 false) | 
|  | ; CHECK-NEXT:    call void @use(i1 true) | 
|  | ; CHECK-NEXT:    [[A_127:%.*]] = and i32 [[A]], 127 | 
|  | ; CHECK-NEXT:    call void @use.i32(i32 [[A_127]]) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       false: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | br i1 %cond, label %bb1, label %bb2 | 
|  |  | 
|  | bb1: | 
|  | br label %pred | 
|  |  | 
|  | bb2: | 
|  | br label %pred | 
|  |  | 
|  | pred: | 
|  | %p = phi i32 [ undef, %bb1 ], [ 10, %bb2 ] | 
|  | %bc.1 = icmp ugt i32 %a, %p | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp eq i32 %a, 5 | 
|  | call void @use(i1 %f.1) | 
|  |  | 
|  | %t.1 = icmp ne i32 %a,  5 | 
|  | call void @use(i1 %t.1) | 
|  |  | 
|  | %a.127 = and i32 %a, 127 | 
|  | call void @use.i32(i32 %a.127) | 
|  |  | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; It is not allowed to use the information from %p as a bound, because an | 
|  | ; incoming value is undef. | 
|  | define void @bound_range_and_undef(i32 %a, i1 %cond) { | 
|  | ; CHECK-LABEL: @bound_range_and_undef( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[A_10:%.*]] = and i32 [[A:%.*]], 127 | 
|  | ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] | 
|  | ; CHECK:       bb1: | 
|  | ; CHECK-NEXT:    br label [[PRED:%.*]] | 
|  | ; CHECK:       bb2: | 
|  | ; CHECK-NEXT:    br label [[PRED]] | 
|  | ; CHECK:       pred: | 
|  | ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[A_10]], [[BB1]] ], [ undef, [[BB2]] ] | 
|  | ; CHECK-NEXT:    [[BC_1:%.*]] = icmp ugt i32 [[A]], [[P]] | 
|  | ; CHECK-NEXT:    br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]] | 
|  | ; CHECK:       true: | 
|  | ; CHECK-NEXT:    [[F_1:%.*]] = icmp eq i32 [[A]], 300 | 
|  | ; CHECK-NEXT:    call void @use(i1 [[F_1]]) | 
|  | ; CHECK-NEXT:    [[A_127_2:%.*]] = and i32 [[P]], 127 | 
|  | ; CHECK-NEXT:    call void @use.i32(i32 [[A_127_2]]) | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       false: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %a.10 = and i32 %a, 127 | 
|  | br i1 %cond, label %bb1, label %bb2 | 
|  |  | 
|  | bb1: | 
|  | br label %pred | 
|  |  | 
|  | bb2: | 
|  | br label %pred | 
|  |  | 
|  | pred: | 
|  | %p = phi i32 [ %a.10, %bb1 ], [ undef, %bb2 ] | 
|  | %bc.1 = icmp ugt i32 %a, %p | 
|  | br i1 %bc.1, label %true, label %false | 
|  |  | 
|  | true: | 
|  | %f.1 = icmp eq i32 %a, 300 | 
|  | call void @use(i1 %f.1) | 
|  |  | 
|  | %a.127.2 = and i32 %p, 127 | 
|  | call void @use.i32(i32 %a.127.2) | 
|  |  | 
|  | ret void | 
|  |  | 
|  | false: | 
|  | ret void | 
|  | } |