| ; 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 nuw nsw 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) | 
 |  | 
 | define void @val_undef_range() { | 
 | ; CHECK-LABEL: @val_undef_range( | 
 | ; CHECK-NEXT:  entry: | 
 | ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw 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:    call void @use.i32(i32 [[A]]) | 
 | ; 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:    call void @use.i32(i32 10) | 
 | ; 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 | 
 | } | 
 |  | 
 | 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:    call void @use.i32(i32 [[P]]) | 
 | ; 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 | 
 | } | 
 |  | 
 | ; It is not allowed to use the range information from the condition to remove | 
 | ; %p.127 = and i32 %p, 127, as %p could be undef. | 
 | define void @masked_incoming_val_with_undef(i32 %a, i1 %cond) { | 
 | ; CHECK-LABEL: @masked_incoming_val_with_undef( | 
 | ; 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:    [[P_127:%.*]] = and i32 [[P]], 127 | 
 | ; CHECK-NEXT:    call void @use.i32(i32 [[P_127]]) | 
 | ; 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 ] | 
 |   %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 | 
 | } |