1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i64 @test_lshr() { 5; CHECK-LABEL: @test_lshr( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: br label [[LOOP:%.*]] 8; CHECK: loop: 9; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 10; CHECK: exit: 11; CHECK-NEXT: ret i64 1023 12; 13entry: 14 br label %loop 15loop: 16 %iv.lshr = phi i64 [1023, %entry], [%iv.lshr.next, %loop] 17 %iv.lshr.next = lshr i64 %iv.lshr, 1 18 br i1 undef, label %exit, label %loop 19exit: 20 %res = or i64 %iv.lshr, 1023 21 ret i64 %res 22} 23 24define i64 @test_ashr_zeros() { 25; CHECK-LABEL: @test_ashr_zeros( 26; CHECK-NEXT: entry: 27; CHECK-NEXT: br label [[LOOP:%.*]] 28; CHECK: loop: 29; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 30; CHECK: exit: 31; CHECK-NEXT: ret i64 1023 32; 33entry: 34 br label %loop 35loop: 36 %iv.ashr = phi i64 [1023, %entry], [%iv.ashr.next, %loop] 37 %iv.ashr.next = ashr i64 %iv.ashr, 1 38 br i1 undef, label %exit, label %loop 39exit: 40 %res = or i64 %iv.ashr, 1023 41 ret i64 %res 42} 43 44define i64 @test_ashr_ones() { 45; CHECK-LABEL: @test_ashr_ones( 46; CHECK-NEXT: entry: 47; CHECK-NEXT: br label [[LOOP:%.*]] 48; CHECK: loop: 49; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 50; CHECK: exit: 51; CHECK-NEXT: ret i64 -1 52; 53entry: 54 br label %loop 55loop: 56 %iv.ashr = phi i64 [-1023, %entry], [%iv.ashr.next, %loop] 57 %iv.ashr.next = ashr i64 %iv.ashr, 1 58 br i1 undef, label %exit, label %loop 59exit: 60 %res = or i64 %iv.ashr, 1023 61 ret i64 %res 62} 63 64; Same as previous, but swapped operands to phi 65define i64 @test_ashr_ones2() { 66; CHECK-LABEL: @test_ashr_ones2( 67; CHECK-NEXT: entry: 68; CHECK-NEXT: br label [[LOOP:%.*]] 69; CHECK: loop: 70; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 71; CHECK: exit: 72; CHECK-NEXT: ret i64 -1 73; 74entry: 75 br label %loop 76loop: 77 %iv.ashr = phi i64 [%iv.ashr.next, %loop], [-1023, %entry] 78 %iv.ashr.next = ashr i64 %iv.ashr, 1 79 br i1 undef, label %exit, label %loop 80exit: 81 %res = or i64 %iv.ashr, 1023 82 ret i64 %res 83} 84 85 86; negative case for when start is unknown 87define i64 @test_ashr_unknown(i64 %start) { 88; CHECK-LABEL: @test_ashr_unknown( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: br label [[LOOP:%.*]] 91; CHECK: loop: 92; CHECK-NEXT: [[IV_ASHR:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_ASHR_NEXT:%.*]], [[LOOP]] ] 93; CHECK-NEXT: [[IV_ASHR_NEXT]] = ashr i64 [[IV_ASHR]], 1 94; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 95; CHECK: exit: 96; CHECK-NEXT: [[RES:%.*]] = or i64 [[IV_ASHR]], 1023 97; CHECK-NEXT: ret i64 [[RES]] 98; 99entry: 100 br label %loop 101loop: 102 %iv.ashr = phi i64 [%start, %entry], [%iv.ashr.next, %loop] 103 %iv.ashr.next = ashr i64 %iv.ashr, 1 104 br i1 undef, label %exit, label %loop 105exit: 106 %res = or i64 %iv.ashr, 1023 107 ret i64 %res 108} 109 110; Negative case where we don't have a (shift) recurrence because the operands 111; of the ashr are swapped. (This does end up being a divide recurrence.) 112define i64 @test_ashr_wrong_op(i64 %start) { 113; CHECK-LABEL: @test_ashr_wrong_op( 114; CHECK-NEXT: entry: 115; CHECK-NEXT: br label [[LOOP:%.*]] 116; CHECK: loop: 117; CHECK-NEXT: [[IV_ASHR:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_ASHR_NEXT:%.*]], [[LOOP]] ] 118; CHECK-NEXT: [[IV_ASHR_NEXT]] = lshr i64 1, [[IV_ASHR]] 119; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 120; CHECK: exit: 121; CHECK-NEXT: [[RES:%.*]] = or i64 [[IV_ASHR]], 1023 122; CHECK-NEXT: ret i64 [[RES]] 123; 124entry: 125 br label %loop 126loop: 127 %iv.ashr = phi i64 [%start, %entry], [%iv.ashr.next, %loop] 128 %iv.ashr.next = ashr i64 1, %iv.ashr 129 br i1 undef, label %exit, label %loop 130exit: 131 %res = or i64 %iv.ashr, 1023 132 ret i64 %res 133} 134 135 136define i64 @test_shl() { 137; CHECK-LABEL: @test_shl( 138; CHECK-NEXT: entry: 139; CHECK-NEXT: br label [[LOOP:%.*]] 140; CHECK: loop: 141; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[LOOP]] 142; CHECK: exit: 143; CHECK-NEXT: ret i64 0 144; 145entry: 146 br label %loop 147loop: 148 %iv.shl = phi i64 [8, %entry], [%iv.shl.next, %loop] 149 %iv.shl.next = shl i64 %iv.shl, 1 150 br i1 undef, label %exit, label %loop 151exit: 152 %res = and i64 %iv.shl, 7 153 ret i64 %res 154} 155