1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt %s -sccp -S | FileCheck --check-prefix=SCCP %s 3; RUN: opt %s -ipsccp -S | FileCheck --check-prefix=IPSCCP %s 4 5; Test different widening scenarios. 6 7declare void @use(i1) 8declare i1 @cond() 9 10define void @test_2_incoming_constants(i32 %x) { 11; SCCP-LABEL: @test_2_incoming_constants( 12; SCCP-NEXT: entry: 13; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 14; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 15; SCCP: bb1: 16; SCCP-NEXT: br label [[EXIT]] 17; SCCP: exit: 18; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ] 19; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 20; SCCP-NEXT: call void @use(i1 true) 21; SCCP-NEXT: call void @use(i1 false) 22; SCCP-NEXT: ret void 23; 24; IPSCCP-LABEL: @test_2_incoming_constants( 25; IPSCCP-NEXT: entry: 26; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 27; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 28; IPSCCP: bb1: 29; IPSCCP-NEXT: br label [[EXIT]] 30; IPSCCP: exit: 31; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ] 32; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 33; IPSCCP-NEXT: call void @use(i1 true) 34; IPSCCP-NEXT: call void @use(i1 false) 35; IPSCCP-NEXT: ret void 36; 37entry: 38 %c.1 = call i1 @cond() 39 br i1 %c.1, label %bb1, label %exit 40 41bb1: 42 br label %exit 43 44exit: 45 %p = phi i32 [0, %entry], [1, %bb1] 46 %a = add i32 %p, 1 47 %t.1 = icmp ult i32 %a, 20 48 call void @use(i1 %t.1) 49 %f.1 = icmp ugt i32 %a, 10 50 call void @use(i1 %f.1) 51 ret void 52} 53 54define void @test_3_incoming_constants(i32 %x) { 55; SCCP-LABEL: @test_3_incoming_constants( 56; SCCP-NEXT: entry: 57; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 58; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 59; SCCP: bb1: 60; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 61; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] 62; SCCP: bb2: 63; SCCP-NEXT: br label [[EXIT]] 64; SCCP: exit: 65; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ] 66; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 67; SCCP-NEXT: call void @use(i1 true) 68; SCCP-NEXT: call void @use(i1 false) 69; SCCP-NEXT: ret void 70; 71; IPSCCP-LABEL: @test_3_incoming_constants( 72; IPSCCP-NEXT: entry: 73; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 74; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 75; IPSCCP: bb1: 76; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 77; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] 78; IPSCCP: bb2: 79; IPSCCP-NEXT: br label [[EXIT]] 80; IPSCCP: exit: 81; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ] 82; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 83; IPSCCP-NEXT: call void @use(i1 true) 84; IPSCCP-NEXT: call void @use(i1 false) 85; IPSCCP-NEXT: ret void 86; 87entry: 88 %c.1 = call i1 @cond() 89 br i1 %c.1, label %bb1, label %exit 90 91bb1: 92 %c.2 = call i1 @cond() 93 br i1 %c.2, label %bb2, label %exit 94 95bb2: 96 br label %exit 97 98exit: 99 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2] 100 %a = add i32 %p, 1 101 %t.1 = icmp ult i32 %a, 20 102 call void @use(i1 %t.1) 103 %f.1 = icmp ugt i32 %a, 10 104 call void @use(i1 %f.1) 105 ret void 106} 107 108define void @test_5_incoming_constants(i32 %x) { 109; SCCP-LABEL: @test_5_incoming_constants( 110; SCCP-NEXT: entry: 111; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 112; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 113; SCCP: bb1: 114; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 115; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] 116; SCCP: bb2: 117; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 118; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 119; SCCP: bb3: 120; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond() 121; SCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]] 122; SCCP: bb4: 123; SCCP-NEXT: br label [[EXIT]] 124; SCCP: exit: 125; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ] 126; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 127; SCCP-NEXT: call void @use(i1 true) 128; SCCP-NEXT: call void @use(i1 false) 129; SCCP-NEXT: ret void 130; 131; IPSCCP-LABEL: @test_5_incoming_constants( 132; IPSCCP-NEXT: entry: 133; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 134; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]] 135; IPSCCP: bb1: 136; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 137; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]] 138; IPSCCP: bb2: 139; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 140; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 141; IPSCCP: bb3: 142; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond() 143; IPSCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]] 144; IPSCCP: bb4: 145; IPSCCP-NEXT: br label [[EXIT]] 146; IPSCCP: exit: 147; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ] 148; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 149; IPSCCP-NEXT: call void @use(i1 true) 150; IPSCCP-NEXT: call void @use(i1 false) 151; IPSCCP-NEXT: ret void 152; 153entry: 154 %c.1 = call i1 @cond() 155 br i1 %c.1, label %bb1, label %exit 156 157bb1: 158 %c.2 = call i1 @cond() 159 br i1 %c.2, label %bb2, label %exit 160 161bb2: 162 %c.3 = call i1 @cond() 163 br i1 %c.3, label %bb3, label %exit 164 165bb3: 166 %c.4 = call i1 @cond() 167 br i1 %c.4, label %bb4, label %exit 168 169bb4: 170 br label %exit 171 172exit: 173 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2], [3, %bb3], [4, %bb4] 174 %a = add i32 %p, 1 175 %t.1 = icmp ult i32 %a, 20 176 call void @use(i1 %t.1) 177 %f.1 = icmp ugt i32 %a, 10 178 call void @use(i1 %f.1) 179 ret void 180} 181 182; For the rotated_loop_* test cases %p and %a are extended on each iteration. 183 184define void @rotated_loop_2(i32 %x) { 185; SCCP-LABEL: @rotated_loop_2( 186; SCCP-NEXT: entry: 187; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 188; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]] 189; SCCP: bb1: 190; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 191; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]] 192; SCCP: bb2: 193; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 194; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 195; SCCP: bb3: 196; SCCP-NEXT: br label [[EXIT]] 197; SCCP: exit: 198; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ] 199; SCCP-NEXT: [[A]] = add i32 [[P]], 1 200; SCCP-NEXT: call void @use(i1 true) 201; SCCP-NEXT: call void @use(i1 false) 202; SCCP-NEXT: br i1 false, label [[EXIT]], label [[EXIT_1:%.*]] 203; SCCP: exit.1: 204; SCCP-NEXT: ret void 205; 206; IPSCCP-LABEL: @rotated_loop_2( 207; IPSCCP-NEXT: entry: 208; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 209; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]] 210; IPSCCP: bb1: 211; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 212; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]] 213; IPSCCP: bb2: 214; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 215; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 216; IPSCCP: bb3: 217; IPSCCP-NEXT: br label [[EXIT]] 218; IPSCCP: exit: 219; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ] 220; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1 221; IPSCCP-NEXT: call void @use(i1 true) 222; IPSCCP-NEXT: call void @use(i1 false) 223; IPSCCP-NEXT: br label [[EXIT_1:%.*]] 224; IPSCCP: exit.1: 225; IPSCCP-NEXT: ret void 226; 227entry: 228 %c.1 = call i1 @cond() 229 br i1 %c.1, label %exit, label %bb1 230 231bb1: 232 %c.2 = call i1 @cond() 233 br i1 %c.2, label %exit, label %bb2 234 235bb2: 236 %c.3 = call i1 @cond() 237 br i1 %c.3, label %bb3, label %exit 238 239bb3: 240 br label %exit 241 242exit: 243 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit] 244 %a = add i32 %p, 1 245 %t.1 = icmp ult i32 %a, 20 246 call void @use(i1 %t.1) 247 %f.1 = icmp ugt i32 %a, 10 248 call void @use(i1 %f.1) 249 %c.4 = icmp ult i32 %a, 2 250 br i1 %c.4, label %exit, label %exit.1 251 252exit.1: 253 ret void 254} 255 256define void @rotated_loop_3(i32 %x) { 257; SCCP-LABEL: @rotated_loop_3( 258; SCCP-NEXT: entry: 259; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 260; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]] 261; SCCP: bb1: 262; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 263; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]] 264; SCCP: bb2: 265; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 266; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 267; SCCP: bb3: 268; SCCP-NEXT: br label [[EXIT]] 269; SCCP: exit: 270; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ] 271; SCCP-NEXT: [[A]] = add i32 [[P]], 1 272; SCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20 273; SCCP-NEXT: call void @use(i1 [[T_1]]) 274; SCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10 275; SCCP-NEXT: call void @use(i1 [[F_1]]) 276; SCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3 277; SCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]] 278; SCCP: exit.1: 279; SCCP-NEXT: ret void 280; 281; IPSCCP-LABEL: @rotated_loop_3( 282; IPSCCP-NEXT: entry: 283; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 284; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]] 285; IPSCCP: bb1: 286; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 287; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]] 288; IPSCCP: bb2: 289; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 290; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]] 291; IPSCCP: bb3: 292; IPSCCP-NEXT: br label [[EXIT]] 293; IPSCCP: exit: 294; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ] 295; IPSCCP-NEXT: [[A]] = add i32 [[P]], 1 296; IPSCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20 297; IPSCCP-NEXT: call void @use(i1 [[T_1]]) 298; IPSCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10 299; IPSCCP-NEXT: call void @use(i1 [[F_1]]) 300; IPSCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3 301; IPSCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]] 302; IPSCCP: exit.1: 303; IPSCCP-NEXT: ret void 304; 305entry: 306 %c.1 = call i1 @cond() 307 br i1 %c.1, label %exit, label %bb1 308 309bb1: 310 %c.2 = call i1 @cond() 311 br i1 %c.2, label %exit, label %bb2 312 313bb2: 314 %c.3 = call i1 @cond() 315 br i1 %c.3, label %bb3, label %exit 316 317bb3: 318 br label %exit 319 320exit: 321 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit] 322 %a = add i32 %p, 1 323 %t.1 = icmp ult i32 %a, 20 324 call void @use(i1 %t.1) 325 %f.1 = icmp ugt i32 %a, 10 326 call void @use(i1 %f.1) 327 %c.4 = icmp ult i32 %a, 3 328 br i1 %c.4, label %exit, label %exit.1 329 330exit.1: 331 ret void 332} 333 334; For the loop_with_header_* tests, %iv and %a change on each iteration, but we 335; can use the range imposed by the condition %c.1 when widening. 336define void @loop_with_header_1(i32 %x) { 337; SCCP-LABEL: @loop_with_header_1( 338; SCCP-NEXT: entry: 339; SCCP-NEXT: br label [[LOOP_HEADER:%.*]] 340; SCCP: loop.header: 341; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ] 342; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2 343; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]] 344; SCCP: loop.body: 345; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 2 346; SCCP-NEXT: call void @use(i1 [[T_1]]) 347; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 348; SCCP-NEXT: br label [[LOOP_HEADER]] 349; SCCP: exit: 350; SCCP-NEXT: ret void 351; 352; IPSCCP-LABEL: @loop_with_header_1( 353; IPSCCP-NEXT: entry: 354; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]] 355; IPSCCP: loop.header: 356; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ] 357; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2 358; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]] 359; IPSCCP: loop.body: 360; IPSCCP-NEXT: call void @use(i1 true) 361; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 362; IPSCCP-NEXT: br label [[LOOP_HEADER]] 363; IPSCCP: exit: 364; IPSCCP-NEXT: ret void 365; 366entry: 367 br label %loop.header 368 369loop.header: 370 %iv = phi i32 [0, %entry], [%iv.next, %loop.body] 371 %c.1 = icmp slt i32 %iv, 2 372 br i1 %c.1, label %loop.body, label %exit 373 374loop.body: 375 %t.1 = icmp slt i32 %iv, 2 376 call void @use(i1 %t.1) 377 %iv.next = add nsw i32 %iv, 1 378 br label %loop.header 379 380exit: 381 ret void 382} 383 384define void @loop_with_header_2(i32 %x) { 385; SCCP-LABEL: @loop_with_header_2( 386; SCCP-NEXT: entry: 387; SCCP-NEXT: br label [[LOOP_HEADER:%.*]] 388; SCCP: loop.header: 389; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ] 390; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200 391; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]] 392; SCCP: loop.body: 393; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 200 394; SCCP-NEXT: call void @use(i1 [[T_1]]) 395; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 396; SCCP-NEXT: br label [[LOOP_HEADER]] 397; SCCP: exit: 398; SCCP-NEXT: ret void 399; 400; IPSCCP-LABEL: @loop_with_header_2( 401; IPSCCP-NEXT: entry: 402; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]] 403; IPSCCP: loop.header: 404; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ] 405; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200 406; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]] 407; IPSCCP: loop.body: 408; IPSCCP-NEXT: call void @use(i1 true) 409; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 410; IPSCCP-NEXT: br label [[LOOP_HEADER]] 411; IPSCCP: exit: 412; IPSCCP-NEXT: ret void 413; 414entry: 415 br label %loop.header 416 417loop.header: 418 %iv = phi i32 [0, %entry], [%iv.next, %loop.body] 419 %c.1 = icmp slt i32 %iv, 200 420 br i1 %c.1, label %loop.body, label %exit 421 422loop.body: 423 %t.1 = icmp slt i32 %iv, 200 424 call void @use(i1 %t.1) 425 %iv.next = add nsw i32 %iv, 1 426 br label %loop.header 427 428exit: 429 ret void 430} 431 432; In the function below, the condition %c.1 results in a range [7, 6), which 433; can be used as a widening bound. It does not fully contain the range we get 434; from combining it with the information from %tmp12. 435define void @foo(i64* %arg) { 436; SCCP-LABEL: @foo( 437; SCCP-NEXT: bb: 438; SCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32 439; SCCP-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0 440; SCCP-NEXT: [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8 441; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [ 442; SCCP-NEXT: i32 1, label [[BB3:%.*]] 443; SCCP-NEXT: i32 2, label [[BB4:%.*]] 444; SCCP-NEXT: i32 4, label [[BB19:%.*]] 445; SCCP-NEXT: ] 446; SCCP: bb3: 447; SCCP-NEXT: unreachable 448; SCCP: bb4: 449; SCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3 450; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3 451; SCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]] 452; SCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1 453; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32 454; SCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64 455; SCCP-NEXT: br label [[BB11:%.*]] 456; SCCP: bb11: 457; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ] 458; SCCP-NEXT: br label [[BB13:%.*]] 459; SCCP: bb13: 460; SCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6 461; SCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]] 462; SCCP: bb15: 463; SCCP-NEXT: unreachable 464; SCCP: bb16: 465; SCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2 466; SCCP-NEXT: br label [[BB18]] 467; SCCP: bb18: 468; SCCP-NEXT: br label [[BB11]] 469; SCCP: bb19: 470; SCCP-NEXT: unreachable 471; SCCP: bb20: 472; SCCP-NEXT: ret void 473; 474; IPSCCP-LABEL: @foo( 475; IPSCCP-NEXT: bb: 476; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32 477; IPSCCP-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0 478; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8 479; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [ 480; IPSCCP-NEXT: i32 1, label [[BB3:%.*]] 481; IPSCCP-NEXT: i32 2, label [[BB4:%.*]] 482; IPSCCP-NEXT: i32 4, label [[BB19:%.*]] 483; IPSCCP-NEXT: ] 484; IPSCCP: bb3: 485; IPSCCP-NEXT: unreachable 486; IPSCCP: bb4: 487; IPSCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3 488; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3 489; IPSCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]] 490; IPSCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1 491; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32 492; IPSCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64 493; IPSCCP-NEXT: br label [[BB11:%.*]] 494; IPSCCP: bb11: 495; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ] 496; IPSCCP-NEXT: br label [[BB13:%.*]] 497; IPSCCP: bb13: 498; IPSCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6 499; IPSCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]] 500; IPSCCP: bb15: 501; IPSCCP-NEXT: unreachable 502; IPSCCP: bb16: 503; IPSCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2 504; IPSCCP-NEXT: br label [[BB18]] 505; IPSCCP: bb18: 506; IPSCCP-NEXT: br label [[BB11]] 507; IPSCCP: bb19: 508; IPSCCP-NEXT: unreachable 509; IPSCCP: bb20: 510; IPSCCP-NEXT: ret void 511; 512bb: 513 %tmp = zext i8 undef to i32 514 %tmp1 = getelementptr inbounds i64, i64* %arg, i32 0 515 %tmp2 = load i64, i64* %tmp1, align 8 516 switch i32 %tmp, label %bb20 [ 517 i32 1, label %bb3 518 i32 2, label %bb4 519 i32 4, label %bb19 520 ] 521 522bb3: ; preds = %bb 523 unreachable 524 525bb4: ; preds = %bb 526 %tmp5 = add i64 %tmp2, 3 527 %tmp6 = and i64 %tmp5, 3 528 %tmp7 = sub i64 3, %tmp6 529 %tmp8 = shl i64 %tmp7, 1 530 %tmp9 = trunc i64 %tmp8 to i32 531 %tmp10 = sext i32 %tmp9 to i64 532 br label %bb11 533 534bb11: ; preds = %bb18, %bb4 535 %tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ] 536 br label %bb13 537 538bb13: ; preds = %bb11 539 %c.1 = icmp eq i64 %tmp12, 6 540 br i1 %c.1, label %bb15, label %bb16 541 542bb15: ; preds = %bb13 543 unreachable 544 545bb16: ; preds = %bb13 546 %tmp17 = add i64 %tmp12, 2 547 br label %bb18 548 549bb18: ; preds = %bb16 550 br label %bb11 551 552bb19: ; preds = %bb 553 unreachable 554 555bb20: ; preds = %bb 556 ret void 557} 558 559; The functions below check that widening with an upper bound does correctly 560; return whether the range changed. Make sure we do not eliminate %c.2. 561 562%struct.baz.1 = type { i32, i32, i8*, i8* } 563%struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }> 564 565@global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1 566 567declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1 568 569define linkonce_odr dereferenceable(1) i8* @spam(%struct.baz.1* %arg, i32 %arg1) align 2 { 570; SCCP-LABEL: @spam( 571; SCCP-NEXT: bb: 572; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3 573; SCCP-NEXT: [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8 574; SCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64 575; SCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]] 576; SCCP-NEXT: ret i8* [[TMP4]] 577; 578; IPSCCP-LABEL: @spam( 579; IPSCCP-NEXT: bb: 580; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3 581; IPSCCP-NEXT: [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8 582; IPSCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64 583; IPSCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]] 584; IPSCCP-NEXT: ret i8* [[TMP4]] 585; 586bb: 587 %tmp = getelementptr inbounds %struct.baz.1, %struct.baz.1* %arg, i32 0, i32 3 588 %tmp2 = load i8*, i8** %tmp, align 8 589 %tmp3 = sext i32 %arg1 to i64 590 %tmp4 = getelementptr inbounds i8, i8* %tmp2, i64 %tmp3 591 ret i8* %tmp4 592} 593 594define i8* @wobble(%struct.blam.2* %arg, i32 %arg1) align 2 { 595; SCCP-LABEL: @wobble( 596; SCCP-NEXT: bb: 597; SCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16 598; SCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]] 599; SCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535 600; SCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8 601; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1 602; SCCP-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8 603; SCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]] 604; SCCP-NEXT: br label [[BB8:%.*]] 605; SCCP: bb8: 606; SCCP-NEXT: [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ] 607; SCCP-NEXT: [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ] 608; SCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ] 609; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8 610; SCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]] 611; SCCP: bb13: 612; SCCP-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 613; SCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]] 614; SCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4 615; SCCP-NEXT: [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]]) 616; SCCP-NEXT: [[TMP18]] = bitcast i8* [[TMP17]] to i16* 617; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2 618; SCCP-NEXT: [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1 619; SCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32 620; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0 621; SCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]] 622; SCCP: bb23: 623; SCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16 624; SCCP-NEXT: store i16 [[TMP24]], i16* [[TMP18]], align 2 625; SCCP-NEXT: br label [[BB31]] 626; SCCP: bb25: 627; SCCP-NEXT: [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2 628; SCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32 629; SCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]] 630; SCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]] 631; SCCP: bb29: 632; SCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1 633; SCCP-NEXT: br label [[BB8]] 634; SCCP: bb31: 635; SCCP-NEXT: [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ] 636; SCCP-NEXT: [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ] 637; SCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0 638; SCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]] 639; SCCP: bb35: 640; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1 641; SCCP-NEXT: br label [[BB66:%.*]] 642; SCCP: bb37: 643; SCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8 644; SCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]] 645; SCCP: bb39: 646; SCCP-NEXT: [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1 647; SCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16 648; SCCP-NEXT: store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1 649; SCCP-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 650; SCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]] 651; SCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4 652; SCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2 653; SCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]]) 654; SCCP-NEXT: [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1 655; SCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32 656; SCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1 657; SCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4 658; SCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2 659; SCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]]) 660; SCCP-NEXT: [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1 661; SCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32 662; SCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]] 663; SCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]] 664; SCCP: bb56: 665; SCCP-NEXT: [[TMP57:%.*]] = add nsw i32 [[TMP40]], -1 666; SCCP-NEXT: br label [[BB60]] 667; SCCP: bb58: 668; SCCP-NEXT: [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8* 669; SCCP-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false) 670; SCCP-NEXT: br label [[BB60]] 671; SCCP: bb60: 672; SCCP-NEXT: [[TMP61:%.*]] = phi i32 [ [[TMP57]], [[BB56]] ], [ [[TMP40]], [[BB39]] ], [ [[TMP11]], [[BB58]] ] 673; SCCP-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 674; SCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1 675; SCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4 676; SCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]]) 677; SCCP-NEXT: br label [[BB66]] 678; SCCP: bb66: 679; SCCP-NEXT: [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ] 680; SCCP-NEXT: ret i8* [[TMP67]] 681; 682; IPSCCP-LABEL: @wobble( 683; IPSCCP-NEXT: bb: 684; IPSCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16 685; IPSCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]] 686; IPSCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535 687; IPSCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8 688; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1 689; IPSCCP-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8 690; IPSCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]] 691; IPSCCP-NEXT: br label [[BB8:%.*]] 692; IPSCCP: bb8: 693; IPSCCP-NEXT: [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ] 694; IPSCCP-NEXT: [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ] 695; IPSCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ] 696; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8 697; IPSCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]] 698; IPSCCP: bb13: 699; IPSCCP-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 700; IPSCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]] 701; IPSCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4 702; IPSCCP-NEXT: [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]]) 703; IPSCCP-NEXT: [[TMP18]] = bitcast i8* [[TMP17]] to i16* 704; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2 705; IPSCCP-NEXT: [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1 706; IPSCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32 707; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0 708; IPSCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]] 709; IPSCCP: bb23: 710; IPSCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16 711; IPSCCP-NEXT: store i16 [[TMP24]], i16* [[TMP18]], align 2 712; IPSCCP-NEXT: br label [[BB31]] 713; IPSCCP: bb25: 714; IPSCCP-NEXT: [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2 715; IPSCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32 716; IPSCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]] 717; IPSCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]] 718; IPSCCP: bb29: 719; IPSCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1 720; IPSCCP-NEXT: br label [[BB8]] 721; IPSCCP: bb31: 722; IPSCCP-NEXT: [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ] 723; IPSCCP-NEXT: [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ] 724; IPSCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0 725; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]] 726; IPSCCP: bb35: 727; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1 728; IPSCCP-NEXT: br label [[BB66:%.*]] 729; IPSCCP: bb37: 730; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8 731; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]] 732; IPSCCP: bb39: 733; IPSCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16 734; IPSCCP-NEXT: store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1 735; IPSCCP-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 736; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7 737; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4 738; IPSCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2 739; IPSCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]]) 740; IPSCCP-NEXT: [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1 741; IPSCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32 742; IPSCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1 743; IPSCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4 744; IPSCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2 745; IPSCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]]) 746; IPSCCP-NEXT: [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1 747; IPSCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32 748; IPSCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]] 749; IPSCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]] 750; IPSCCP: bb56: 751; IPSCCP-NEXT: br label [[BB60]] 752; IPSCCP: bb58: 753; IPSCCP-NEXT: [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8* 754; IPSCCP-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false) 755; IPSCCP-NEXT: br label [[BB60]] 756; IPSCCP: bb60: 757; IPSCCP-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ] 758; IPSCCP-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0 759; IPSCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1 760; IPSCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4 761; IPSCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]]) 762; IPSCCP-NEXT: br label [[BB66]] 763; IPSCCP: bb66: 764; IPSCCP-NEXT: [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ] 765; IPSCCP-NEXT: ret i8* [[TMP67]] 766; 767bb: 768 %tmp = lshr i32 %arg1, 16 769 %tmp2 = xor i32 %tmp, %arg1 770 %tmp3 = and i32 %tmp2, 65535 771 %tmp4 = mul i32 %arg1, 8 772 %tmp5 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 1 773 %tmp6 = load i32, i32* %tmp5, align 8 774 %tmp7 = and i32 %tmp4, %tmp6 775 br label %bb8 776 777bb8: ; preds = %bb29, %bb 778 %tmp9 = phi i8* [ undef, %bb ], [ %tmp17, %bb29 ] 779 %tmp10 = phi i16* [ undef, %bb ], [ %tmp18, %bb29 ] 780 %tmp11 = phi i32 [ 0, %bb ], [ %tmp30, %bb29 ] 781 %c.1 = icmp slt i32 %tmp11, 8 782 br i1 %c.1, label %bb13, label %bb31 783 784bb13: ; preds = %bb8 785 %tmp14 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0 786 %tmp15 = add i32 %tmp7, %tmp11 787 %tmp16 = mul i32 %tmp15, 4 788 %tmp17 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp14, i32 %tmp16) 789 %tmp18 = bitcast i8* %tmp17 to i16* 790 %tmp19 = getelementptr inbounds i8, i8* %tmp17, i64 2 791 %tmp20 = load i8, i8* %tmp19, align 1 792 %tmp21 = zext i8 %tmp20 to i32 793 %tmp22 = icmp eq i32 %tmp21, 0 794 br i1 %tmp22, label %bb23, label %bb25 795 796bb23: ; preds = %bb13 797 %tmp24 = trunc i32 %tmp3 to i16 798 store i16 %tmp24, i16* %tmp18, align 2 799 br label %bb31 800 801bb25: ; preds = %bb13 802 %tmp26 = load i16, i16* %tmp18, align 2 803 %tmp27 = zext i16 %tmp26 to i32 804 %tmp28 = icmp eq i32 %tmp27, %tmp3 805 br i1 %tmp28, label %bb31, label %bb29 806 807bb29: ; preds = %bb25 808 %tmp30 = add nsw i32 %tmp11, 1 809 br label %bb8 810 811bb31: ; preds = %bb25, %bb23, %bb8 812 %tmp32 = phi i8* [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp9, %bb8 ] 813 %tmp33 = phi i16* [ %tmp18, %bb23 ], [ %tmp18, %bb25 ], [ %tmp10, %bb8 ] 814 %tmp34 = icmp eq i32 %tmp11, 0 815 br i1 %tmp34, label %bb35, label %bb37 816 817bb35: ; preds = %bb31 818 %tmp36 = getelementptr inbounds i8, i8* %tmp32, i64 1 819 br label %bb66 820 821bb37: ; preds = %bb31 822 %c.2 = icmp eq i32 %tmp11, 8 823 br i1 %c.2, label %bb39, label %bb58 824 825bb39: ; preds = %bb37 826 %tmp40 = add nsw i32 %tmp11, -1 827 %tmp41 = trunc i32 %tmp3 to i16 828 store i16 %tmp41, i16* bitcast ([4 x i8]* @global.11 to i16*), align 1 829 %tmp42 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0 830 %tmp43 = add i32 %tmp7, %tmp40 831 %tmp44 = mul i32 %tmp43, 4 832 %tmp45 = add i32 %tmp44, 2 833 %tmp46 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp45) 834 %tmp47 = load i8, i8* %tmp46, align 1 835 %tmp48 = zext i8 %tmp47 to i32 836 %tmp49 = sub i32 %tmp43, 1 837 %tmp50 = mul i32 %tmp49, 4 838 %tmp51 = add i32 %tmp50, 2 839 %tmp52 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp51) 840 %tmp53 = load i8, i8* %tmp52, align 1 841 %tmp54 = zext i8 %tmp53 to i32 842 %tmp55 = icmp sgt i32 %tmp48, %tmp54 843 br i1 %tmp55, label %bb56, label %bb60 844 845bb56: ; preds = %bb39 846 %tmp57 = add nsw i32 %tmp40, -1 847 br label %bb60 848 849bb58: ; preds = %bb37 850 %tmp59 = bitcast i16* %tmp33 to i8* 851 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 %tmp59, i64 4, i1 false) 852 br label %bb60 853 854bb60: ; preds = %bb58, %bb56, %bb39 855 %tmp61 = phi i32 [ %tmp57, %bb56 ], [ %tmp40, %bb39 ], [ %tmp11, %bb58 ] 856 %tmp62 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0 857 %tmp63 = add i32 %tmp7, 1 858 %tmp64 = mul i32 %tmp63, 4 859 %tmp65 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp62, i32 %tmp64) 860 br label %bb66 861 862bb66: ; preds = %bb60, %bb35 863 %tmp67 = phi i8* [ %tmp36, %bb35 ], [ null, %bb60 ] 864 ret i8* %tmp67 865} 866 867 868define i32 @loop_with_multiple_euqal_incomings(i32 %N) { 869; SCCP-LABEL: @loop_with_multiple_euqal_incomings( 870; SCCP-NEXT: entry: 871; SCCP-NEXT: br label [[LOOP:%.*]] 872; SCCP: loop: 873; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ] 874; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 875; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] 876; SCCP: bb1: 877; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 878; SCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]] 879; SCCP: bb2: 880; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond() 881; SCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]] 882; SCCP: bb3: 883; SCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1 884; SCCP-NEXT: br label [[LOOP]] 885; SCCP: bb4: 886; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 887; SCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]] 888; SCCP: bb5: 889; SCCP-NEXT: br label [[LOOP]] 890; SCCP: bb6: 891; SCCP-NEXT: br label [[LOOP]] 892; SCCP: end: 893; SCCP-NEXT: ret i32 [[P]] 894; 895; IPSCCP-LABEL: @loop_with_multiple_euqal_incomings( 896; IPSCCP-NEXT: entry: 897; IPSCCP-NEXT: br label [[LOOP:%.*]] 898; IPSCCP: loop: 899; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ] 900; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond() 901; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] 902; IPSCCP: bb1: 903; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond() 904; IPSCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]] 905; IPSCCP: bb2: 906; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond() 907; IPSCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]] 908; IPSCCP: bb3: 909; IPSCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1 910; IPSCCP-NEXT: br label [[LOOP]] 911; IPSCCP: bb4: 912; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond() 913; IPSCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]] 914; IPSCCP: bb5: 915; IPSCCP-NEXT: br label [[LOOP]] 916; IPSCCP: bb6: 917; IPSCCP-NEXT: br label [[LOOP]] 918; IPSCCP: end: 919; IPSCCP-NEXT: ret i32 [[P]] 920; 921entry: 922 br label %loop 923 924loop: 925 %p = phi i32 [ 0, %entry ], [ %p.next, %bb3 ], [ 0, %bb4 ], [ 0, %bb5], [ 0, %bb6 ] 926 %c.1 = call i1 @cond() 927 br i1 %c.1, label %bb1, label %bb2 928 929bb1: 930 %c.2 = call i1 @cond() 931 br i1 %c.2, label %bb3, label %bb4 932 933bb2: 934 %c.4 = call i1 @cond() 935 br i1 %c.4, label %bb5, label %bb6 936 937bb3: 938 %p.next = add i32 %p, 1 939 br label %loop 940 941bb4: 942 %c.3 = call i1 @cond() 943 br i1 %c.3, label %loop, label %end 944 945bb5: 946 br label %loop 947 948bb6: 949 br label %loop 950 951end: 952 ret i32 %p 953} 954