1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -debugify-and-strip-all-safe < %s -mtriple=aarch64-linux-gnu | FileCheck %s 3 4; marked as external to prevent possible optimizations 5@a = external global i32 6@b = external global i32 7@c = external global i32 8@d = external global i32 9 10; (a > 10 && b == c) || (a >= 10 && b == d) 11define i32 @combine_gt_ge_10() #0 { 12; CHECK-LABEL: combine_gt_ge_10: 13; CHECK: // %bb.0: // %entry 14; CHECK-NEXT: adrp x8, :got:a 15; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 16; CHECK-NEXT: ldr w8, [x8] 17; CHECK-NEXT: cmp w8, #10 18; CHECK-NEXT: adrp x8, :got:b 19; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 20; CHECK-NEXT: b.le .LBB0_3 21; CHECK-NEXT: // %bb.1: // %land.lhs.true 22; CHECK-NEXT: adrp x9, :got:c 23; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 24; CHECK-NEXT: ldr w10, [x8] 25; CHECK-NEXT: ldr w9, [x9] 26; CHECK-NEXT: cmp w10, w9 27; CHECK-NEXT: b.ne .LBB0_4 28; CHECK-NEXT: // %bb.2: 29; CHECK-NEXT: mov w0, #1 // =0x1 30; CHECK-NEXT: ret 31; CHECK-NEXT: .LBB0_3: // %lor.lhs.false 32; CHECK-NEXT: b.lt .LBB0_6 33; CHECK-NEXT: .LBB0_4: // %land.lhs.true3 34; CHECK-NEXT: adrp x9, :got:d 35; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 36; CHECK-NEXT: ldr w8, [x8] 37; CHECK-NEXT: ldr w9, [x9] 38; CHECK-NEXT: cmp w8, w9 39; CHECK-NEXT: b.ne .LBB0_6 40; CHECK-NEXT: // %bb.5: 41; CHECK-NEXT: mov w0, #1 // =0x1 42; CHECK-NEXT: ret 43; CHECK-NEXT: .LBB0_6: // %if.end 44; CHECK-NEXT: mov w0, wzr 45; CHECK-NEXT: ret 46entry: 47 %0 = load i32, ptr @a, align 4 48 %cmp = icmp sgt i32 %0, 10 49 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 50 51land.lhs.true: ; preds = %entry 52 %1 = load i32, ptr @b, align 4 53 %2 = load i32, ptr @c, align 4 54 %cmp1 = icmp eq i32 %1, %2 55 br i1 %cmp1, label %return, label %land.lhs.true3 56 57lor.lhs.false: ; preds = %entry 58 %cmp2 = icmp sgt i32 %0, 9 59 br i1 %cmp2, label %land.lhs.true3, label %if.end 60 61land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true 62 %3 = load i32, ptr @b, align 4 63 %4 = load i32, ptr @d, align 4 64 %cmp4 = icmp eq i32 %3, %4 65 br i1 %cmp4, label %return, label %if.end 66 67if.end: ; preds = %land.lhs.true3, %lor.lhs.false 68 br label %return 69 70return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 71 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 72 ret i32 %retval.0 73} 74 75; (a > 5 && b == c) || (a < 5 && b == d) 76define i32 @combine_gt_lt_5() #0 { 77; CHECK-LABEL: combine_gt_lt_5: 78; CHECK: // %bb.0: // %entry 79; CHECK-NEXT: adrp x8, :got:a 80; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 81; CHECK-NEXT: ldr w8, [x8] 82; CHECK-NEXT: cmp w8, #5 83; CHECK-NEXT: b.le .LBB1_3 84; CHECK-NEXT: // %bb.1: // %land.lhs.true 85; CHECK-NEXT: adrp x8, :got:b 86; CHECK-NEXT: adrp x9, :got:c 87; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 88; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 89; CHECK-NEXT: ldr w8, [x8] 90; CHECK-NEXT: ldr w9, [x9] 91; CHECK-NEXT: cmp w8, w9 92; CHECK-NEXT: b.ne .LBB1_6 93; CHECK-NEXT: // %bb.2: 94; CHECK-NEXT: mov w0, #1 // =0x1 95; CHECK-NEXT: ret 96; CHECK-NEXT: .LBB1_3: // %lor.lhs.false 97; CHECK-NEXT: b.ge .LBB1_6 98; CHECK-NEXT: // %bb.4: // %land.lhs.true3 99; CHECK-NEXT: adrp x8, :got:b 100; CHECK-NEXT: adrp x9, :got:d 101; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 102; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 103; CHECK-NEXT: ldr w8, [x8] 104; CHECK-NEXT: ldr w9, [x9] 105; CHECK-NEXT: cmp w8, w9 106; CHECK-NEXT: b.ne .LBB1_6 107; CHECK-NEXT: // %bb.5: 108; CHECK-NEXT: mov w0, #1 // =0x1 109; CHECK-NEXT: ret 110; CHECK-NEXT: .LBB1_6: // %if.end 111; CHECK-NEXT: mov w0, wzr 112; CHECK-NEXT: ret 113entry: 114 %0 = load i32, ptr @a, align 4 115 %cmp = icmp sgt i32 %0, 5 116 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 117 118land.lhs.true: ; preds = %entry 119 %1 = load i32, ptr @b, align 4 120 %2 = load i32, ptr @c, align 4 121 %cmp1 = icmp eq i32 %1, %2 122 br i1 %cmp1, label %return, label %if.end 123 124lor.lhs.false: ; preds = %entry 125 %cmp2 = icmp slt i32 %0, 5 126 br i1 %cmp2, label %land.lhs.true3, label %if.end 127 128land.lhs.true3: ; preds = %lor.lhs.false 129 %3 = load i32, ptr @b, align 4 130 %4 = load i32, ptr @d, align 4 131 %cmp4 = icmp eq i32 %3, %4 132 br i1 %cmp4, label %return, label %if.end 133 134if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true 135 br label %return 136 137return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 138 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 139 ret i32 %retval.0 140} 141 142; (a < 5 && b == c) || (a <= 5 && b == d) 143define i32 @combine_lt_ge_5() #0 { 144; CHECK-LABEL: combine_lt_ge_5: 145; CHECK: // %bb.0: // %entry 146; CHECK-NEXT: adrp x8, :got:a 147; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 148; CHECK-NEXT: ldr w8, [x8] 149; CHECK-NEXT: cmp w8, #5 150; CHECK-NEXT: adrp x8, :got:b 151; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 152; CHECK-NEXT: b.ge .LBB2_3 153; CHECK-NEXT: // %bb.1: // %land.lhs.true 154; CHECK-NEXT: adrp x9, :got:c 155; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 156; CHECK-NEXT: ldr w10, [x8] 157; CHECK-NEXT: ldr w9, [x9] 158; CHECK-NEXT: cmp w10, w9 159; CHECK-NEXT: b.ne .LBB2_4 160; CHECK-NEXT: // %bb.2: 161; CHECK-NEXT: mov w0, #1 // =0x1 162; CHECK-NEXT: ret 163; CHECK-NEXT: .LBB2_3: // %lor.lhs.false 164; CHECK-NEXT: b.gt .LBB2_6 165; CHECK-NEXT: .LBB2_4: // %land.lhs.true3 166; CHECK-NEXT: adrp x9, :got:d 167; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 168; CHECK-NEXT: ldr w8, [x8] 169; CHECK-NEXT: ldr w9, [x9] 170; CHECK-NEXT: cmp w8, w9 171; CHECK-NEXT: b.ne .LBB2_6 172; CHECK-NEXT: // %bb.5: 173; CHECK-NEXT: mov w0, #1 // =0x1 174; CHECK-NEXT: ret 175; CHECK-NEXT: .LBB2_6: // %if.end 176; CHECK-NEXT: mov w0, wzr 177; CHECK-NEXT: ret 178entry: 179 %0 = load i32, ptr @a, align 4 180 %cmp = icmp slt i32 %0, 5 181 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 182 183land.lhs.true: ; preds = %entry 184 %1 = load i32, ptr @b, align 4 185 %2 = load i32, ptr @c, align 4 186 %cmp1 = icmp eq i32 %1, %2 187 br i1 %cmp1, label %return, label %land.lhs.true3 188 189lor.lhs.false: ; preds = %entry 190 %cmp2 = icmp slt i32 %0, 6 191 br i1 %cmp2, label %land.lhs.true3, label %if.end 192 193land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true 194 %3 = load i32, ptr @b, align 4 195 %4 = load i32, ptr @d, align 4 196 %cmp4 = icmp eq i32 %3, %4 197 br i1 %cmp4, label %return, label %if.end 198 199if.end: ; preds = %land.lhs.true3, %lor.lhs.false 200 br label %return 201 202return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 203 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 204 ret i32 %retval.0 205} 206 207; (a < 5 && b == c) || (a > 5 && b == d) 208define i32 @combine_lt_gt_5() #0 { 209; CHECK-LABEL: combine_lt_gt_5: 210; CHECK: // %bb.0: // %entry 211; CHECK-NEXT: adrp x8, :got:a 212; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 213; CHECK-NEXT: ldr w8, [x8] 214; CHECK-NEXT: cmp w8, #5 215; CHECK-NEXT: b.ge .LBB3_3 216; CHECK-NEXT: // %bb.1: // %land.lhs.true 217; CHECK-NEXT: adrp x8, :got:b 218; CHECK-NEXT: adrp x9, :got:c 219; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 220; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 221; CHECK-NEXT: ldr w8, [x8] 222; CHECK-NEXT: ldr w9, [x9] 223; CHECK-NEXT: cmp w8, w9 224; CHECK-NEXT: b.ne .LBB3_6 225; CHECK-NEXT: // %bb.2: 226; CHECK-NEXT: mov w0, #1 // =0x1 227; CHECK-NEXT: ret 228; CHECK-NEXT: .LBB3_3: // %lor.lhs.false 229; CHECK-NEXT: b.le .LBB3_6 230; CHECK-NEXT: // %bb.4: // %land.lhs.true3 231; CHECK-NEXT: adrp x8, :got:b 232; CHECK-NEXT: adrp x9, :got:d 233; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 234; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 235; CHECK-NEXT: ldr w8, [x8] 236; CHECK-NEXT: ldr w9, [x9] 237; CHECK-NEXT: cmp w8, w9 238; CHECK-NEXT: b.ne .LBB3_6 239; CHECK-NEXT: // %bb.5: 240; CHECK-NEXT: mov w0, #1 // =0x1 241; CHECK-NEXT: ret 242; CHECK-NEXT: .LBB3_6: // %if.end 243; CHECK-NEXT: mov w0, wzr 244; CHECK-NEXT: ret 245entry: 246 %0 = load i32, ptr @a, align 4 247 %cmp = icmp slt i32 %0, 5 248 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 249 250land.lhs.true: ; preds = %entry 251 %1 = load i32, ptr @b, align 4 252 %2 = load i32, ptr @c, align 4 253 %cmp1 = icmp eq i32 %1, %2 254 br i1 %cmp1, label %return, label %if.end 255 256lor.lhs.false: ; preds = %entry 257 %cmp2 = icmp sgt i32 %0, 5 258 br i1 %cmp2, label %land.lhs.true3, label %if.end 259 260land.lhs.true3: ; preds = %lor.lhs.false 261 %3 = load i32, ptr @b, align 4 262 %4 = load i32, ptr @d, align 4 263 %cmp4 = icmp eq i32 %3, %4 264 br i1 %cmp4, label %return, label %if.end 265 266if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true 267 br label %return 268 269return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 270 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 271 ret i32 %retval.0 272} 273 274; (a > -5 && b == c) || (a < -5 && b == d) 275define i32 @combine_gt_lt_n5() #0 { 276; CHECK-LABEL: combine_gt_lt_n5: 277; CHECK: // %bb.0: // %entry 278; CHECK-NEXT: adrp x8, :got:a 279; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 280; CHECK-NEXT: ldr w8, [x8] 281; CHECK-NEXT: cmn w8, #5 282; CHECK-NEXT: b.le .LBB4_3 283; CHECK-NEXT: // %bb.1: // %land.lhs.true 284; CHECK-NEXT: adrp x8, :got:b 285; CHECK-NEXT: adrp x9, :got:c 286; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 287; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 288; CHECK-NEXT: ldr w8, [x8] 289; CHECK-NEXT: ldr w9, [x9] 290; CHECK-NEXT: cmp w8, w9 291; CHECK-NEXT: b.ne .LBB4_6 292; CHECK-NEXT: // %bb.2: 293; CHECK-NEXT: mov w0, #1 // =0x1 294; CHECK-NEXT: ret 295; CHECK-NEXT: .LBB4_3: // %lor.lhs.false 296; CHECK-NEXT: b.ge .LBB4_6 297; CHECK-NEXT: // %bb.4: // %land.lhs.true3 298; CHECK-NEXT: adrp x8, :got:b 299; CHECK-NEXT: adrp x9, :got:d 300; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 301; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 302; CHECK-NEXT: ldr w8, [x8] 303; CHECK-NEXT: ldr w9, [x9] 304; CHECK-NEXT: cmp w8, w9 305; CHECK-NEXT: b.ne .LBB4_6 306; CHECK-NEXT: // %bb.5: 307; CHECK-NEXT: mov w0, #1 // =0x1 308; CHECK-NEXT: ret 309; CHECK-NEXT: .LBB4_6: // %if.end 310; CHECK-NEXT: mov w0, wzr 311; CHECK-NEXT: ret 312entry: 313 %0 = load i32, ptr @a, align 4 314 %cmp = icmp sgt i32 %0, -5 315 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 316 317land.lhs.true: ; preds = %entry 318 %1 = load i32, ptr @b, align 4 319 %2 = load i32, ptr @c, align 4 320 %cmp1 = icmp eq i32 %1, %2 321 br i1 %cmp1, label %return, label %if.end 322 323lor.lhs.false: ; preds = %entry 324 %cmp2 = icmp slt i32 %0, -5 325 br i1 %cmp2, label %land.lhs.true3, label %if.end 326 327land.lhs.true3: ; preds = %lor.lhs.false 328 %3 = load i32, ptr @b, align 4 329 %4 = load i32, ptr @d, align 4 330 %cmp4 = icmp eq i32 %3, %4 331 br i1 %cmp4, label %return, label %if.end 332 333if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true 334 br label %return 335 336return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 337 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 338 ret i32 %retval.0 339} 340 341; (a < -5 && b == c) || (a > -5 && b == d) 342define i32 @combine_lt_gt_n5() #0 { 343; CHECK-LABEL: combine_lt_gt_n5: 344; CHECK: // %bb.0: // %entry 345; CHECK-NEXT: adrp x8, :got:a 346; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 347; CHECK-NEXT: ldr w8, [x8] 348; CHECK-NEXT: cmn w8, #5 349; CHECK-NEXT: b.ge .LBB5_3 350; CHECK-NEXT: // %bb.1: // %land.lhs.true 351; CHECK-NEXT: adrp x8, :got:b 352; CHECK-NEXT: adrp x9, :got:c 353; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 354; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 355; CHECK-NEXT: ldr w8, [x8] 356; CHECK-NEXT: ldr w9, [x9] 357; CHECK-NEXT: cmp w8, w9 358; CHECK-NEXT: b.ne .LBB5_6 359; CHECK-NEXT: // %bb.2: 360; CHECK-NEXT: mov w0, #1 // =0x1 361; CHECK-NEXT: ret 362; CHECK-NEXT: .LBB5_3: // %lor.lhs.false 363; CHECK-NEXT: b.le .LBB5_6 364; CHECK-NEXT: // %bb.4: // %land.lhs.true3 365; CHECK-NEXT: adrp x8, :got:b 366; CHECK-NEXT: adrp x9, :got:d 367; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 368; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 369; CHECK-NEXT: ldr w8, [x8] 370; CHECK-NEXT: ldr w9, [x9] 371; CHECK-NEXT: cmp w8, w9 372; CHECK-NEXT: b.ne .LBB5_6 373; CHECK-NEXT: // %bb.5: 374; CHECK-NEXT: mov w0, #1 // =0x1 375; CHECK-NEXT: ret 376; CHECK-NEXT: .LBB5_6: // %if.end 377; CHECK-NEXT: mov w0, wzr 378; CHECK-NEXT: ret 379entry: 380 %0 = load i32, ptr @a, align 4 381 %cmp = icmp slt i32 %0, -5 382 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false 383 384land.lhs.true: ; preds = %entry 385 %1 = load i32, ptr @b, align 4 386 %2 = load i32, ptr @c, align 4 387 %cmp1 = icmp eq i32 %1, %2 388 br i1 %cmp1, label %return, label %if.end 389 390lor.lhs.false: ; preds = %entry 391 %cmp2 = icmp sgt i32 %0, -5 392 br i1 %cmp2, label %land.lhs.true3, label %if.end 393 394land.lhs.true3: ; preds = %lor.lhs.false 395 %3 = load i32, ptr @b, align 4 396 %4 = load i32, ptr @d, align 4 397 %cmp4 = icmp eq i32 %3, %4 398 br i1 %cmp4, label %return, label %if.end 399 400if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true 401 br label %return 402 403return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 404 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 405 ret i32 %retval.0 406} 407 408%struct.Struct = type { i64, i64 } 409 410@glob = internal unnamed_addr global ptr null, align 8 411 412declare ptr @Update(ptr) #1 413 414; no checks for this case, it just should be processed without errors 415define void @combine_non_adjacent_cmp_br(ptr nocapture readonly %hdCall) #0 { 416; CHECK-LABEL: combine_non_adjacent_cmp_br: 417; CHECK: // %bb.0: // %entry 418; CHECK-NEXT: str x30, [sp, #-48]! // 8-byte Folded Spill 419; CHECK-NEXT: .cfi_def_cfa_offset 48 420; CHECK-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill 421; CHECK-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill 422; CHECK-NEXT: .cfi_offset w19, -8 423; CHECK-NEXT: .cfi_offset w20, -16 424; CHECK-NEXT: .cfi_offset w21, -24 425; CHECK-NEXT: .cfi_offset w22, -32 426; CHECK-NEXT: .cfi_offset w30, -48 427; CHECK-NEXT: ldr x20, [x0] 428; CHECK-NEXT: mov w19, #24 // =0x18 429; CHECK-NEXT: adrp x22, glob 430; CHECK-NEXT: add x21, x20, #2 431; CHECK-NEXT: .LBB6_1: // %land.rhs 432; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 433; CHECK-NEXT: ldr x8, [x19] 434; CHECK-NEXT: cmp x8, #1 435; CHECK-NEXT: b.lt .LBB6_3 436; CHECK-NEXT: // %bb.2: // %while.body 437; CHECK-NEXT: // in Loop: Header=BB6_1 Depth=1 438; CHECK-NEXT: ldr x0, [x22, :lo12:glob] 439; CHECK-NEXT: bl Update 440; CHECK-NEXT: sub x21, x21, #2 441; CHECK-NEXT: cmp x20, x21 442; CHECK-NEXT: b.lt .LBB6_1 443; CHECK-NEXT: .LBB6_3: // %while.end 444; CHECK-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload 445; CHECK-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload 446; CHECK-NEXT: ldr x30, [sp], #48 // 8-byte Folded Reload 447; CHECK-NEXT: .cfi_def_cfa_offset 0 448; CHECK-NEXT: .cfi_restore w19 449; CHECK-NEXT: .cfi_restore w20 450; CHECK-NEXT: .cfi_restore w21 451; CHECK-NEXT: .cfi_restore w22 452; CHECK-NEXT: .cfi_restore w30 453; CHECK-NEXT: ret 454entry: 455 %0 = load i64, ptr %hdCall, align 8 456 br label %land.rhs 457 458land.rhs: 459 %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ] 460 %1 = load i64, ptr inttoptr (i64 24 to ptr), align 8 461 %cmp2 = icmp sgt i64 %1, 0 462 br i1 %cmp2, label %while.body, label %while.end 463 464while.body: 465 %2 = load ptr, ptr @glob, align 8 466 %call = tail call ptr @Update(ptr %2) #2 467 %sub = add nsw i64 %rp.06, -2 468 %cmp = icmp slt i64 %0, %rp.06 469 br i1 %cmp, label %land.rhs, label %while.end 470 471while.end: 472 ret void 473} 474 475; undefined external to prevent possible optimizations 476declare void @do_something() #1 477 478define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 { 479; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ: 480; CHECK: // %bb.0: // %entry 481; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 482; CHECK-NEXT: .cfi_def_cfa_offset 32 483; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 484; CHECK-NEXT: .cfi_offset w19, -8 485; CHECK-NEXT: .cfi_offset w20, -16 486; CHECK-NEXT: .cfi_offset w30, -32 487; CHECK-NEXT: adrp x19, :got:a 488; CHECK-NEXT: ldr x19, [x19, :got_lo12:a] 489; CHECK-NEXT: ldr w8, [x19] 490; CHECK-NEXT: cmn w8, #2 491; CHECK-NEXT: b.gt .LBB7_4 492; CHECK-NEXT: // %bb.1: // %while.body.preheader 493; CHECK-NEXT: sub w20, w8, #1 494; CHECK-NEXT: .LBB7_2: // %while.body 495; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 496; CHECK-NEXT: bl do_something 497; CHECK-NEXT: adds w20, w20, #1 498; CHECK-NEXT: b.mi .LBB7_2 499; CHECK-NEXT: // %bb.3: // %while.cond.while.end_crit_edge 500; CHECK-NEXT: ldr w8, [x19] 501; CHECK-NEXT: .LBB7_4: // %while.end 502; CHECK-NEXT: cmp w8, #1 503; CHECK-NEXT: b.gt .LBB7_7 504; CHECK-NEXT: // %bb.5: // %land.lhs.true 505; CHECK-NEXT: adrp x8, :got:b 506; CHECK-NEXT: adrp x9, :got:d 507; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 508; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 509; CHECK-NEXT: ldr w8, [x8] 510; CHECK-NEXT: ldr w9, [x9] 511; CHECK-NEXT: cmp w8, w9 512; CHECK-NEXT: b.ne .LBB7_7 513; CHECK-NEXT: // %bb.6: 514; CHECK-NEXT: mov w0, #123 // =0x7b 515; CHECK-NEXT: b .LBB7_8 516; CHECK-NEXT: .LBB7_7: // %if.end 517; CHECK-NEXT: mov w0, wzr 518; CHECK-NEXT: .LBB7_8: // %return 519; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 520; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 521; CHECK-NEXT: .cfi_def_cfa_offset 0 522; CHECK-NEXT: .cfi_restore w19 523; CHECK-NEXT: .cfi_restore w20 524; CHECK-NEXT: .cfi_restore w30 525; CHECK-NEXT: ret 526entry: 527 %0 = load i32, ptr @a, align 4 528 %cmp4 = icmp slt i32 %0, -1 529 br i1 %cmp4, label %while.body.preheader, label %while.end 530 531while.body.preheader: ; preds = %entry 532 br label %while.body 533 534while.body: ; preds = %while.body, %while.body.preheader 535 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ] 536 tail call void @do_something() #2 537 %inc = add nsw i32 %i.05, 1 538 %cmp = icmp slt i32 %i.05, 0 539 br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge 540 541while.cond.while.end_crit_edge: ; preds = %while.body 542 %.pre = load i32, ptr @a, align 4 543 br label %while.end 544 545while.end: ; preds = %while.cond.while.end_crit_edge, %entry 546 %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ] 547 %cmp1 = icmp slt i32 %1, 2 548 br i1 %cmp1, label %land.lhs.true, label %if.end 549 550land.lhs.true: ; preds = %while.end 551 %2 = load i32, ptr @b, align 4 552 %3 = load i32, ptr @d, align 4 553 %cmp2 = icmp eq i32 %2, %3 554 br i1 %cmp2, label %return, label %if.end 555 556if.end: ; preds = %land.lhs.true, %while.end 557 br label %return 558 559return: ; preds = %if.end, %land.lhs.true 560 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ] 561 ret i32 %retval.0 562} 563 564define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 { 565; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other: 566; CHECK: // %bb.0: // %entry 567; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 568; CHECK-NEXT: .cfi_def_cfa_offset 16 569; CHECK-NEXT: .cfi_offset w19, -8 570; CHECK-NEXT: .cfi_offset w30, -16 571; CHECK-NEXT: .cfi_remember_state 572; CHECK-NEXT: adrp x8, :got:a 573; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 574; CHECK-NEXT: ldr w8, [x8] 575; CHECK-NEXT: cmp w8, #0 576; CHECK-NEXT: b.gt .LBB8_3 577; CHECK-NEXT: // %bb.1: // %while.body.preheader 578; CHECK-NEXT: sub w19, w8, #1 579; CHECK-NEXT: .LBB8_2: // %while.body 580; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 581; CHECK-NEXT: bl do_something 582; CHECK-NEXT: adds w19, w19, #1 583; CHECK-NEXT: b.mi .LBB8_2 584; CHECK-NEXT: .LBB8_3: // %while.end 585; CHECK-NEXT: adrp x8, :got:c 586; CHECK-NEXT: ldr x8, [x8, :got_lo12:c] 587; CHECK-NEXT: ldr w8, [x8] 588; CHECK-NEXT: cmn w8, #2 589; CHECK-NEXT: b.lt .LBB8_6 590; CHECK-NEXT: // %bb.4: // %land.lhs.true 591; CHECK-NEXT: adrp x8, :got:b 592; CHECK-NEXT: adrp x9, :got:d 593; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 594; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 595; CHECK-NEXT: ldr w8, [x8] 596; CHECK-NEXT: ldr w9, [x9] 597; CHECK-NEXT: cmp w8, w9 598; CHECK-NEXT: b.ne .LBB8_6 599; CHECK-NEXT: // %bb.5: 600; CHECK-NEXT: mov w0, #123 // =0x7b 601; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 602; CHECK-NEXT: .cfi_def_cfa_offset 0 603; CHECK-NEXT: .cfi_restore w19 604; CHECK-NEXT: .cfi_restore w30 605; CHECK-NEXT: ret 606; CHECK-NEXT: .LBB8_6: // %if.end 607; CHECK-NEXT: .cfi_restore_state 608; CHECK-NEXT: mov w0, wzr 609; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 610; CHECK-NEXT: .cfi_def_cfa_offset 0 611; CHECK-NEXT: .cfi_restore w19 612; CHECK-NEXT: .cfi_restore w30 613; CHECK-NEXT: ret 614entry: 615 %0 = load i32, ptr @a, align 4 616 %cmp4 = icmp slt i32 %0, 1 617 br i1 %cmp4, label %while.body.preheader, label %while.end 618 619while.body.preheader: ; preds = %entry 620 br label %while.body 621 622while.body: ; preds = %while.body, %while.body.preheader 623 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ] 624 tail call void @do_something() #2 625 %inc = add nsw i32 %i.05, 1 626 %cmp = icmp slt i32 %i.05, 0 627 br i1 %cmp, label %while.body, label %while.end.loopexit 628 629while.end.loopexit: ; preds = %while.body 630 br label %while.end 631 632while.end: ; preds = %while.end.loopexit, %entry 633 %1 = load i32, ptr @c, align 4 634 %cmp1 = icmp sgt i32 %1, -3 635 br i1 %cmp1, label %land.lhs.true, label %if.end 636 637land.lhs.true: ; preds = %while.end 638 %2 = load i32, ptr @b, align 4 639 %3 = load i32, ptr @d, align 4 640 %cmp2 = icmp eq i32 %2, %3 641 br i1 %cmp2, label %return, label %if.end 642 643if.end: ; preds = %land.lhs.true, %while.end 644 br label %return 645 646return: ; preds = %if.end, %land.lhs.true 647 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ] 648 ret i32 %retval.0 649} 650 651; Test in the following case, we don't hit 'cmp' and trigger a false positive 652; cmp w19, #0 653; cinc w0, w19, gt 654; ... 655; fcmp d8, #0.0 656; b.gt .LBB0_5 657 658define i32 @fcmpri(i32 %argc, ptr nocapture readonly %argv) #0 { 659; CHECK-LABEL: fcmpri: 660; CHECK: // %bb.0: // %entry 661; CHECK-NEXT: cmp w0, #2 662; CHECK-NEXT: b.lt .LBB9_3 663; CHECK-NEXT: // %bb.1: // %land.lhs.true 664; CHECK-NEXT: ldr x8, [x1, #8] 665; CHECK-NEXT: cbz x8, .LBB9_3 666; CHECK-NEXT: // %bb.2: 667; CHECK-NEXT: mov w0, #3 // =0x3 668; CHECK-NEXT: ret 669; CHECK-NEXT: .LBB9_3: // %if.end 670; CHECK-NEXT: str d8, [sp, #-32]! // 8-byte Folded Spill 671; CHECK-NEXT: .cfi_def_cfa_offset 32 672; CHECK-NEXT: stp x30, x19, [sp, #16] // 16-byte Folded Spill 673; CHECK-NEXT: .cfi_offset w19, -8 674; CHECK-NEXT: .cfi_offset w30, -16 675; CHECK-NEXT: .cfi_offset b8, -32 676; CHECK-NEXT: mov w0, #1 // =0x1 677; CHECK-NEXT: bl zoo 678; CHECK-NEXT: mov w19, w0 679; CHECK-NEXT: mov w0, #-1 // =0xffffffff 680; CHECK-NEXT: bl yoo 681; CHECK-NEXT: cmp w19, #0 682; CHECK-NEXT: mov w1, #2 // =0x2 683; CHECK-NEXT: fmov d8, d0 684; CHECK-NEXT: cinc w0, w19, gt 685; CHECK-NEXT: bl xoo 686; CHECK-NEXT: fmov d0, #-1.00000000 687; CHECK-NEXT: fcmp d8, #0.0 688; CHECK-NEXT: fmov d1, #-2.00000000 689; CHECK-NEXT: fadd d0, d8, d0 690; CHECK-NEXT: fcsel d0, d8, d0, gt 691; CHECK-NEXT: bl woo 692; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload 693; CHECK-NEXT: mov w0, #4 // =0x4 694; CHECK-NEXT: ldr d8, [sp], #32 // 8-byte Folded Reload 695; CHECK-NEXT: .cfi_def_cfa_offset 0 696; CHECK-NEXT: .cfi_restore w19 697; CHECK-NEXT: .cfi_restore w30 698; CHECK-NEXT: .cfi_restore b8 699; CHECK-NEXT: ret 700 701; CHECK-LABEL-DAG: .LBB9_3 702 703entry: 704 %cmp = icmp sgt i32 %argc, 1 705 br i1 %cmp, label %land.lhs.true, label %if.end 706 707land.lhs.true: ; preds = %entry 708 %arrayidx = getelementptr inbounds ptr, ptr %argv, i64 1 709 %0 = load ptr, ptr %arrayidx, align 8 710 %cmp1 = icmp eq ptr %0, null 711 br i1 %cmp1, label %if.end, label %return 712 713if.end: ; preds = %land.lhs.true, %entry 714 %call = call i32 @zoo(i32 1) 715 %call2 = call double @yoo(i32 -1) 716 %cmp4 = icmp sgt i32 %call, 0 717 %add = zext i1 %cmp4 to i32 718 %cond = add nsw i32 %add, %call 719 %call7 = call i32 @xoo(i32 %cond, i32 2) 720 %cmp9 = fcmp ogt double %call2, 0.000000e+00 721 br i1 %cmp9, label %cond.end14, label %cond.false12 722 723cond.false12: ; preds = %if.end 724 %sub = fadd fast double %call2, -1.000000e+00 725 br label %cond.end14 726 727cond.end14: ; preds = %if.end, %cond.false12 728 %cond15 = phi double [ %sub, %cond.false12 ], [ %call2, %if.end ] 729 %call16 = call i32 @woo(double %cond15, double -2.000000e+00) 730 br label %return 731 732return: ; preds = %land.lhs.true, %cond.end14 733 %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ] 734 ret i32 %retval.0 735} 736 737define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) #0 { 738; CHECK-LABEL: cmp_shifted: 739; CHECK: // %bb.0: // %common.ret 740; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 741; CHECK-NEXT: .cfi_def_cfa_offset 16 742; CHECK-NEXT: .cfi_offset w30, -16 743; CHECK-NEXT: mov w8, #42 // =0x2a 744; CHECK-NEXT: cmp w0, #0 745; CHECK-NEXT: mov w9, #128 // =0x80 746; CHECK-NEXT: csinc w8, w8, wzr, gt 747; CHECK-NEXT: cmp w0, #2, lsl #12 // =8192 748; CHECK-NEXT: csel w0, w9, w8, ge 749; CHECK-NEXT: bl zoo 750; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 751; CHECK-NEXT: .cfi_def_cfa_offset 0 752; CHECK-NEXT: .cfi_restore w30 753; CHECK-NEXT: ret 754; [...] 755 756 %tst_low = icmp sgt i32 %in, 8191 757 br i1 %tst_low, label %true, label %false 758 759true: 760 call i32 @zoo(i32 128) 761 ret void 762 763false: 764 %tst = icmp sgt i32 %in, 0 765 br i1 %tst, label %truer, label %falser 766 767truer: 768 call i32 @zoo(i32 42) 769 ret void 770 771falser: 772 call i32 @zoo(i32 1) 773 ret void 774} 775 776define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 { 777; CHECK-LABEL: combine_gt_ge_sel: 778; CHECK: // %bb.0: // %entry 779; CHECK-NEXT: adrp x8, :got:a 780; CHECK-NEXT: ldr x8, [x8, :got_lo12:a] 781; CHECK-NEXT: ldr w8, [x8] 782; CHECK-NEXT: cmp w8, #0 783; CHECK-NEXT: csel x9, x0, xzr, gt 784; CHECK-NEXT: str x9, [x1] 785; CHECK-NEXT: b.le .LBB11_2 786; CHECK-NEXT: // %bb.1: // %lor.lhs.false 787; CHECK-NEXT: cmp w8, #2 788; CHECK-NEXT: b.ge .LBB11_4 789; CHECK-NEXT: b .LBB11_6 790; CHECK-NEXT: .LBB11_2: // %land.lhs.true 791; CHECK-NEXT: adrp x8, :got:b 792; CHECK-NEXT: adrp x9, :got:c 793; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 794; CHECK-NEXT: ldr x9, [x9, :got_lo12:c] 795; CHECK-NEXT: ldr w8, [x8] 796; CHECK-NEXT: ldr w9, [x9] 797; CHECK-NEXT: cmp w8, w9 798; CHECK-NEXT: b.ne .LBB11_4 799; CHECK-NEXT: // %bb.3: 800; CHECK-NEXT: mov w0, #1 // =0x1 801; CHECK-NEXT: ret 802; CHECK-NEXT: .LBB11_4: // %land.lhs.true3 803; CHECK-NEXT: adrp x8, :got:b 804; CHECK-NEXT: adrp x9, :got:d 805; CHECK-NEXT: ldr x8, [x8, :got_lo12:b] 806; CHECK-NEXT: ldr x9, [x9, :got_lo12:d] 807; CHECK-NEXT: ldr w8, [x8] 808; CHECK-NEXT: ldr w9, [x9] 809; CHECK-NEXT: cmp w8, w9 810; CHECK-NEXT: b.ne .LBB11_6 811; CHECK-NEXT: // %bb.5: 812; CHECK-NEXT: mov w0, #1 // =0x1 813; CHECK-NEXT: ret 814; CHECK-NEXT: .LBB11_6: // %if.end 815; CHECK-NEXT: mov w0, wzr 816; CHECK-NEXT: ret 817entry: 818 %0 = load i32, ptr @a, align 4 819 %cmp = icmp sgt i32 %0, 0 820 %m = select i1 %cmp, i64 %v, i64 0 821 store i64 %m, ptr %p 822 br i1 %cmp, label %lor.lhs.false, label %land.lhs.true 823 824land.lhs.true: ; preds = %entry 825 %1 = load i32, ptr @b, align 4 826 %2 = load i32, ptr @c, align 4 827 %cmp1 = icmp eq i32 %1, %2 828 br i1 %cmp1, label %return, label %land.lhs.true3 829 830lor.lhs.false: ; preds = %entry 831 %cmp2 = icmp sgt i32 %0, 1 832 br i1 %cmp2, label %land.lhs.true3, label %if.end 833 834land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true 835 %3 = load i32, ptr @b, align 4 836 %4 = load i32, ptr @d, align 4 837 %cmp4 = icmp eq i32 %3, %4 838 br i1 %cmp4, label %return, label %if.end 839 840if.end: ; preds = %land.lhs.true3, %lor.lhs.false 841 br label %return 842 843return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true 844 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] 845 ret i32 %retval.0 846} 847 848declare i32 @zoo(i32) 849 850declare double @yoo(i32) 851 852declare i32 @xoo(i32, i32) 853 854declare i32 @woo(double, double) 855 856attributes #0 = { uwtable } 857