1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s 3 4declare void @bar() nounwind 5 6define i32 @test1(ptr %a, i32 %b, ptr %c, i32 %d) nounwind { 7; CHECK-LABEL: define i32 @test1 8; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0:[0-9]+]] { 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 11; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 12; CHECK: if.then: 13; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 14; CHECK-NEXT: br label [[IF_END7:%.*]] 15; CHECK: if.else: 16; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 17; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true 18; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 19; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 20; CHECK-NEXT: br label [[IF_END7]] 21; CHECK: if.end7: 22; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_ELSE]] ] 23; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4 24; CHECK-NEXT: ret i32 [[TMP9]] 25; 26entry: 27 %tobool = icmp eq i32 %b, 0 28 br i1 %tobool, label %if.else, label %if.then 29 30if.then: ; preds = %entry 31 tail call void @bar() nounwind 32 br label %if.end7 33 34if.else: ; preds = %entry 35 %tobool3 = icmp eq i32 %d, 0 36 br i1 %tobool3, label %if.end7, label %if.then4 37 38if.then4: ; preds = %if.else 39 tail call void @bar() nounwind 40 br label %if.end7 41 42if.end7: ; preds = %if.else, %if.then4, %if.then 43 %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ] 44 %tmp9 = load i32, ptr %x.0 45 ret i32 %tmp9 46} 47 48define i32 @test1_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 { 49; CHECK-LABEL: define i32 @test1_no_null_opt 50; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1:[0-9]+]] { 51; CHECK-NEXT: entry: 52; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 53; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 54; CHECK: if.then: 55; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 56; CHECK-NEXT: br label [[IF_END7:%.*]] 57; CHECK: if.else: 58; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 59; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]] 60; CHECK: if.then4: 61; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 62; CHECK-NEXT: br label [[IF_END7]] 63; CHECK: if.end7: 64; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_THEN4]] ], [ null, [[IF_ELSE]] ] 65; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4 66; CHECK-NEXT: ret i32 [[TMP9]] 67; 68entry: 69 %tobool = icmp eq i32 %b, 0 70 br i1 %tobool, label %if.else, label %if.then 71 72if.then: ; preds = %entry 73 tail call void @bar() nounwind 74 br label %if.end7 75 76if.else: ; preds = %entry 77 %tobool3 = icmp eq i32 %d, 0 78 br i1 %tobool3, label %if.end7, label %if.then4 79 80if.then4: ; preds = %if.else 81 tail call void @bar() nounwind 82 br label %if.end7 83 84if.end7: ; preds = %if.else, %if.then4, %if.then 85 %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ] 86 %tmp9 = load i32, ptr %x.0 87 ret i32 %tmp9 88} 89 90define i32 @test2(ptr %a, i32 %b, ptr %c, i32 %d) nounwind { 91; CHECK-LABEL: define i32 @test2 92; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] { 93; CHECK-NEXT: entry: 94; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 95; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 96; CHECK: if.then: 97; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 98; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[A]], align 4 99; CHECK-NEXT: ret i32 [[TMP9]] 100; CHECK: if.else: 101; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 102; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true 103; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 104; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 105; CHECK-NEXT: unreachable 106; 107entry: 108 %tobool = icmp eq i32 %b, 0 109 br i1 %tobool, label %if.else, label %if.then 110 111if.then: ; preds = %entry 112 tail call void @bar() nounwind 113 br label %if.end7 114 115if.else: ; preds = %entry 116 %tobool3 = icmp eq i32 %d, 0 117 br i1 %tobool3, label %if.end7, label %if.then4 118 119if.then4: ; preds = %if.else 120 tail call void @bar() nounwind 121 br label %if.end7 122 123if.end7: ; preds = %if.else, %if.then4, %if.then 124 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 125 %tmp9 = load i32, ptr %x.0 126 ret i32 %tmp9 127} 128 129define i32 @test2_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 { 130; CHECK-LABEL: define i32 @test2_no_null_opt 131; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] { 132; CHECK-NEXT: entry: 133; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 134; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 135; CHECK: if.then: 136; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 137; CHECK-NEXT: br label [[IF_END7:%.*]] 138; CHECK: if.else: 139; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 140; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]] 141; CHECK: if.then4: 142; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 143; CHECK-NEXT: br label [[IF_END7]] 144; CHECK: if.end7: 145; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ] 146; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4 147; CHECK-NEXT: ret i32 [[TMP9]] 148; 149entry: 150 %tobool = icmp eq i32 %b, 0 151 br i1 %tobool, label %if.else, label %if.then 152 153if.then: ; preds = %entry 154 tail call void @bar() nounwind 155 br label %if.end7 156 157if.else: ; preds = %entry 158 %tobool3 = icmp eq i32 %d, 0 159 br i1 %tobool3, label %if.end7, label %if.then4 160 161if.then4: ; preds = %if.else 162 tail call void @bar() nounwind 163 br label %if.end7 164 165if.end7: ; preds = %if.else, %if.then4, %if.then 166 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 167 %tmp9 = load i32, ptr %x.0 168 ret i32 %tmp9 169} 170 171define i32 @test3(ptr %a, i32 %b, ptr %c, i32 %d) nounwind { 172; CHECK-LABEL: define i32 @test3 173; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] { 174; CHECK-NEXT: entry: 175; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 176; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 177; CHECK: if.then: 178; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 179; CHECK-NEXT: br label [[IF_END7:%.*]] 180; CHECK: if.else: 181; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 182; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]] 183; CHECK: if.then4: 184; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 185; CHECK-NEXT: br label [[IF_END7]] 186; CHECK: if.end7: 187; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ] 188; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 189; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4 190; CHECK-NEXT: ret i32 [[TMP9]] 191; 192entry: 193 %tobool = icmp eq i32 %b, 0 194 br i1 %tobool, label %if.else, label %if.then 195 196if.then: ; preds = %entry 197 tail call void @bar() nounwind 198 br label %if.end7 199 200if.else: ; preds = %entry 201 %tobool3 = icmp eq i32 %d, 0 202 br i1 %tobool3, label %if.end7, label %if.then4 203 204if.then4: ; preds = %if.else 205 tail call void @bar() nounwind 206 br label %if.end7 207 208if.end7: ; preds = %if.else, %if.then4, %if.then 209 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 210 tail call void @bar() nounwind 211 %tmp9 = load i32, ptr %x.0 212 ret i32 %tmp9 213} 214 215define i32 @test3_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 { 216; CHECK-LABEL: define i32 @test3_no_null_opt 217; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] { 218; CHECK-NEXT: entry: 219; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 220; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 221; CHECK: if.then: 222; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 223; CHECK-NEXT: br label [[IF_END7:%.*]] 224; CHECK: if.else: 225; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 226; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]] 227; CHECK: if.then4: 228; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 229; CHECK-NEXT: br label [[IF_END7]] 230; CHECK: if.end7: 231; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ] 232; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 233; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4 234; CHECK-NEXT: ret i32 [[TMP9]] 235; 236entry: 237 %tobool = icmp eq i32 %b, 0 238 br i1 %tobool, label %if.else, label %if.then 239 240if.then: ; preds = %entry 241 tail call void @bar() nounwind 242 br label %if.end7 243 244if.else: ; preds = %entry 245 %tobool3 = icmp eq i32 %d, 0 246 br i1 %tobool3, label %if.end7, label %if.then4 247 248if.then4: ; preds = %if.else 249 tail call void @bar() nounwind 250 br label %if.end7 251 252if.end7: ; preds = %if.else, %if.then4, %if.then 253 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 254 tail call void @bar() nounwind 255 %tmp9 = load i32, ptr %x.0 256 ret i32 %tmp9 257} 258 259define i32 @test4(ptr %a, i32 %b, ptr %c, i32 %d) nounwind { 260; CHECK-LABEL: define i32 @test4 261; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] { 262; CHECK-NEXT: entry: 263; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 264; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 265; CHECK: if.then: 266; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 267; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i32 10 268; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4 269; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], 1 270; CHECK-NEXT: store i32 [[TMP10]], ptr [[GEP]], align 4 271; CHECK-NEXT: ret i32 [[TMP9]] 272; CHECK: if.else: 273; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 274; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true 275; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 276; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 277; CHECK-NEXT: unreachable 278; 279entry: 280 %tobool = icmp eq i32 %b, 0 281 br i1 %tobool, label %if.else, label %if.then 282 283if.then: ; preds = %entry 284 tail call void @bar() nounwind 285 br label %if.end7 286 287if.else: ; preds = %entry 288 %tobool3 = icmp eq i32 %d, 0 289 br i1 %tobool3, label %if.end7, label %if.then4 290 291if.then4: ; preds = %if.else 292 tail call void @bar() nounwind 293 br label %if.end7 294 295if.end7: ; preds = %if.else, %if.then4, %if.then 296 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 297 %gep = getelementptr i32, ptr %x.0, i32 10 298 %tmp9 = load i32, ptr %gep 299 %tmp10 = or i32 %tmp9, 1 300 store i32 %tmp10, ptr %gep 301 ret i32 %tmp9 302} 303 304define i32 @test4_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 { 305; CHECK-LABEL: define i32 @test4_no_null_opt 306; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] { 307; CHECK-NEXT: entry: 308; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0 309; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 310; CHECK: if.then: 311; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 312; CHECK-NEXT: br label [[IF_END7:%.*]] 313; CHECK: if.else: 314; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0 315; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]] 316; CHECK: if.then4: 317; CHECK-NEXT: tail call void @bar() #[[ATTR0]] 318; CHECK-NEXT: br label [[IF_END7]] 319; CHECK: if.end7: 320; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ] 321; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[X_0]], i32 10 322; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4 323; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], 1 324; CHECK-NEXT: store i32 [[TMP10]], ptr [[GEP]], align 4 325; CHECK-NEXT: ret i32 [[TMP9]] 326; 327entry: 328 %tobool = icmp eq i32 %b, 0 329 br i1 %tobool, label %if.else, label %if.then 330 331if.then: ; preds = %entry 332 tail call void @bar() nounwind 333 br label %if.end7 334 335if.else: ; preds = %entry 336 %tobool3 = icmp eq i32 %d, 0 337 br i1 %tobool3, label %if.end7, label %if.then4 338 339if.then4: ; preds = %if.else 340 tail call void @bar() nounwind 341 br label %if.end7 342 343if.end7: ; preds = %if.else, %if.then4, %if.then 344 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ] 345 %gep = getelementptr i32, ptr %x.0, i32 10 346 %tmp9 = load i32, ptr %gep 347 %tmp10 = or i32 %tmp9, 1 348 store i32 %tmp10, ptr %gep 349 ret i32 %tmp9 350} 351 352attributes #0 = { null_pointer_is_valid } 353