299 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s3 4declare void @use(i1)5 6; We can simplify the conditions in the true block, because the condition7; allows us to replace all uses of %a in the block with a constant.8define void @val_undef_eq() {9; CHECK-LABEL: @val_undef_eq(10; CHECK-NEXT: entry:11; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 undef, 012; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[A]], 1013; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]14; CHECK: true:15; CHECK-NEXT: call void @use(i1 false)16; CHECK-NEXT: call void @use(i1 true)17; CHECK-NEXT: ret void18; CHECK: false:19; CHECK-NEXT: ret void20;21entry:22 %a = add i32 undef, 023 %bc.1 = icmp eq i32 %a, 1024 br i1 %bc.1, label %true, label %false25 26true:27 %f.1 = icmp ne i32 %a, 1028 call void @use(i1 %f.1)29 %f.2 = icmp eq i32 %a, 1030 call void @use(i1 %f.2)31 ret void32 33false:34 ret void35}36 37declare void @use.i32(i32)38 39define void @val_undef_range() {40; CHECK-LABEL: @val_undef_range(41; CHECK-NEXT: entry:42; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 undef, 043; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[A]], 12744; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]45; CHECK: true:46; CHECK-NEXT: call void @use(i1 false)47; CHECK-NEXT: call void @use.i32(i32 [[A]])48; CHECK-NEXT: ret void49; CHECK: false:50; CHECK-NEXT: ret void51;52entry:53 %a = add i32 undef, 054 %bc.1 = icmp ult i32 %a, 12755 br i1 %bc.1, label %true, label %false56 57true:58 %f.1 = icmp eq i32 %a, 12859 call void @use(i1 %f.1)60 61 %a.127 = and i32 %a, 12762 call void @use.i32(i32 %a.127)63 ret void64 65false:66 ret void67}68 69; All uses of %p can be replaced by a constant (10).70define void @val_singlecrfromundef_range(i1 %cond) {71; CHECK-LABEL: @val_singlecrfromundef_range(72; CHECK-NEXT: entry:73; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]74; CHECK: inc1:75; CHECK-NEXT: br label [[IF:%.*]]76; CHECK: inc2:77; CHECK-NEXT: br label [[IF]]78; CHECK: if:79; CHECK-NEXT: br label [[TRUE:%.*]]80; CHECK: true:81; CHECK-NEXT: call void @use(i1 false)82; CHECK-NEXT: call void @use.i32(i32 10)83; CHECK-NEXT: ret void84;85entry:86 87 br i1 %cond, label %inc1, label %inc288 89inc1:90 br label %if91 92inc2:93 br label %if94 95if:96 %p = phi i32 [ 10, %inc1 ], [ undef, %inc2 ]97 %bc.1 = icmp ult i32 %p, 12798 br i1 %bc.1, label %true, label %false99 100true:101 %f.1 = icmp eq i32 %p, 128102 call void @use(i1 %f.1)103 104 %p.127 = and i32 %p, 127105 call void @use.i32(i32 %p.127)106 ret void107 108false:109 ret void110}111 112define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) {113; CHECK-LABEL: @val_undef_to_cr_to_overdef_range(114; CHECK-NEXT: entry:115; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A:%.*]], 127116; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]117; CHECK: inc1:118; CHECK-NEXT: br label [[IF:%.*]]119; CHECK: inc2:120; CHECK-NEXT: br label [[IF]]121; CHECK: if:122; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A_127]], [[INC1]] ], [ undef, [[INC2]] ]123; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[P]], 100124; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]125; CHECK: true:126; CHECK-NEXT: call void @use(i1 false)127; CHECK-NEXT: call void @use.i32(i32 [[P]])128; CHECK-NEXT: ret void129; CHECK: false:130; CHECK-NEXT: ret void131;132entry:133 %a.127 = and i32 %a, 127134 br i1 %cond, label %inc1, label %inc2135 136inc1:137 br label %if138 139inc2:140 br label %if141 142if:143 %p = phi i32 [ %a.127, %inc1 ], [ undef, %inc2 ]144 %bc.1 = icmp ult i32 %p, 100145 br i1 %bc.1, label %true, label %false146 147true:148 %f.1 = icmp eq i32 %p, 128149 call void @use(i1 %f.1)150 151 %p.127 = and i32 %p, 127152 call void @use.i32(i32 %p.127)153 ret void154 155false:156 ret void157}158 159; It is not allowed to use the range information from the condition to remove160; %p.127 = and i32 %p, 127, as %p could be undef.161define void @masked_incoming_val_with_undef(i32 %a, i1 %cond) {162; CHECK-LABEL: @masked_incoming_val_with_undef(163; CHECK-NEXT: entry:164; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A:%.*]], 127165; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]166; CHECK: inc1:167; CHECK-NEXT: br label [[IF:%.*]]168; CHECK: inc2:169; CHECK-NEXT: br label [[IF]]170; CHECK: if:171; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A_127]], [[INC1]] ], [ undef, [[INC2]] ]172; CHECK-NEXT: [[P_127:%.*]] = and i32 [[P]], 127173; CHECK-NEXT: call void @use.i32(i32 [[P_127]])174; CHECK-NEXT: ret void175;176entry:177 %a.127 = and i32 %a, 127178 br i1 %cond, label %inc1, label %inc2179 180inc1:181 br label %if182 183inc2:184 br label %if185 186if:187 %p = phi i32 [ %a.127, %inc1 ], [ undef, %inc2 ]188 %p.127 = and i32 %p, 127189 call void @use.i32(i32 %p.127)190 ret void191 192false:193 ret void194}195 196; All uses of %p can be replaced by a constant (10), we are allowed to use it197; as a bound too.198define void @bound_singlecrfromundef(i32 %a, i1 %cond) {199; CHECK-LABEL: @bound_singlecrfromundef(200; CHECK-NEXT: entry:201; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]202; CHECK: bb1:203; CHECK-NEXT: br label [[PRED:%.*]]204; CHECK: bb2:205; CHECK-NEXT: br label [[PRED]]206; CHECK: pred:207; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10208; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]209; CHECK: true:210; CHECK-NEXT: call void @use(i1 false)211; CHECK-NEXT: call void @use(i1 true)212; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127213; CHECK-NEXT: call void @use.i32(i32 [[A_127]])214; CHECK-NEXT: ret void215; CHECK: false:216; CHECK-NEXT: ret void217;218entry:219 br i1 %cond, label %bb1, label %bb2220 221bb1:222 br label %pred223 224bb2:225 br label %pred226 227pred:228 %p = phi i32 [ undef, %bb1 ], [ 10, %bb2 ]229 %bc.1 = icmp ugt i32 %a, %p230 br i1 %bc.1, label %true, label %false231 232true:233 %f.1 = icmp eq i32 %a, 5234 call void @use(i1 %f.1)235 236 %t.1 = icmp ne i32 %a, 5237 call void @use(i1 %t.1)238 239 %a.127 = and i32 %a, 127240 call void @use.i32(i32 %a.127)241 242 ret void243 244false:245 ret void246}247 248; It is not allowed to use the information from %p as a bound, because an249; incoming value is undef.250define void @bound_range_and_undef(i32 %a, i1 %cond) {251; CHECK-LABEL: @bound_range_and_undef(252; CHECK-NEXT: entry:253; CHECK-NEXT: [[A_10:%.*]] = and i32 [[A:%.*]], 127254; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]255; CHECK: bb1:256; CHECK-NEXT: br label [[PRED:%.*]]257; CHECK: bb2:258; CHECK-NEXT: br label [[PRED]]259; CHECK: pred:260; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A_10]], [[BB1]] ], [ undef, [[BB2]] ]261; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A]], [[P]]262; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]263; CHECK: true:264; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 300265; CHECK-NEXT: call void @use(i1 [[F_1]])266; CHECK-NEXT: [[A_127_2:%.*]] = and i32 [[P]], 127267; CHECK-NEXT: call void @use.i32(i32 [[A_127_2]])268; CHECK-NEXT: ret void269; CHECK: false:270; CHECK-NEXT: ret void271;272entry:273 %a.10 = and i32 %a, 127274 br i1 %cond, label %bb1, label %bb2275 276bb1:277 br label %pred278 279bb2:280 br label %pred281 282pred:283 %p = phi i32 [ %a.10, %bb1 ], [ undef, %bb2 ]284 %bc.1 = icmp ugt i32 %a, %p285 br i1 %bc.1, label %true, label %false286 287true:288 %f.1 = icmp eq i32 %a, 300289 call void @use(i1 %f.1)290 291 %a.127.2 = and i32 %p, 127292 call void @use.i32(i32 %a.127.2)293 294 ret void295 296false:297 ret void298}299