Home | History | Annotate | Download | only in StraightLineStrengthReduce
      1 ; RUN: opt < %s -slsr -gvn -S | FileCheck %s
      2 
      3 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
      4 
      5 define void @slsr1(i32 %b, i32 %s) {
      6 ; CHECK-LABEL: @slsr1(
      7   ; foo(b * s);
      8   %mul0 = mul i32 %b, %s
      9 ; CHECK: mul i32
     10 ; CHECK-NOT: mul i32
     11   call void @foo(i32 %mul0)
     12 
     13   ; foo((b + 1) * s);
     14   %b1 = add i32 %b, 1
     15   %mul1 = mul i32 %b1, %s
     16   call void @foo(i32 %mul1)
     17 
     18   ; foo((b + 2) * s);
     19   %b2 = add i32 %b, 2
     20   %mul2 = mul i32 %b2, %s
     21   call void @foo(i32 %mul2)
     22 
     23   ret void
     24 }
     25 
     26 define void @non_canonicalized(i32 %b, i32 %s) {
     27 ; CHECK-LABEL: @non_canonicalized(
     28   ; foo(b * s);
     29   %mul0 = mul i32 %b, %s
     30 ; CHECK: mul i32
     31 ; CHECK-NOT: mul i32
     32   call void @foo(i32 %mul0)
     33 
     34   ; foo((1 + b) * s);
     35   %b1 = add i32 1, %b
     36   %mul1 = mul i32 %b1, %s
     37   call void @foo(i32 %mul1)
     38 
     39   ; foo((2 + b) * s);
     40   %b2 = add i32 2, %b
     41   %mul2 = mul i32 %b2, %s
     42   call void @foo(i32 %mul2)
     43 
     44   ret void
     45 }
     46 
     47 define void @or(i32 %a, i32 %s) {
     48   %b = shl i32 %a, 1
     49 ; CHECK-LABEL: @or(
     50   ; foo(b * s);
     51   %mul0 = mul i32 %b, %s
     52 ; CHECK: [[base:[^ ]+]] = mul i32
     53   call void @foo(i32 %mul0)
     54 
     55   ; foo((b | 1) * s);
     56   %b1 = or i32 %b, 1
     57   %mul1 = mul i32 %b1, %s
     58 ; CHECK: add i32 [[base]], %s
     59   call void @foo(i32 %mul1)
     60 
     61   ; foo((b | 2) * s);
     62   %b2 = or i32 %b, 2
     63   %mul2 = mul i32 %b2, %s
     64 ; CHECK: mul i32 %b2, %s
     65   call void @foo(i32 %mul2)
     66 
     67   ret void
     68 }
     69 
     70 ; foo(a * b)
     71 ; foo((a + 1) * b)
     72 ; foo(a * (b + 1))
     73 ; foo((a + 1) * (b + 1))
     74 define void @slsr2(i32 %a, i32 %b) {
     75 ; CHECK-LABEL: @slsr2(
     76   %a1 = add i32 %a, 1
     77   %b1 = add i32 %b, 1
     78   %mul0 = mul i32 %a, %b
     79 ; CHECK: mul i32
     80 ; CHECK-NOT: mul i32
     81   %mul1 = mul i32 %a1, %b
     82   %mul2 = mul i32 %a, %b1
     83   %mul3 = mul i32 %a1, %b1
     84 
     85   call void @foo(i32 %mul0)
     86   call void @foo(i32 %mul1)
     87   call void @foo(i32 %mul2)
     88   call void @foo(i32 %mul3)
     89 
     90   ret void
     91 }
     92 
     93 ; The bump is a multiple of the stride.
     94 ;
     95 ; foo(b * s);
     96 ; foo((b + 2) * s);
     97 ; foo((b + 4) * s);
     98 ;   =>
     99 ; mul0 = b * s;
    100 ; bump = s * 2;
    101 ; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
    102 ; mul2 = mul1 + bump;
    103 define void @slsr3(i32 %b, i32 %s) {
    104 ; CHECK-LABEL: @slsr3(
    105   %mul0 = mul i32 %b, %s
    106 ; CHECK: mul i32
    107   call void @foo(i32 %mul0)
    108 
    109   %b1 = add i32 %b, 2
    110   %mul1 = mul i32 %b1, %s
    111 ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = shl i32 %s, 1
    112 ; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
    113   call void @foo(i32 %mul1)
    114 
    115   %b2 = add i32 %b, 4
    116   %mul2 = mul i32 %b2, %s
    117 ; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
    118   call void @foo(i32 %mul2)
    119 
    120   ret void
    121 }
    122 
    123 ; Do not rewrite a candidate if its potential basis does not dominate it.
    124 ;
    125 ; if (cond)
    126 ;   foo(a * b);
    127 ; foo((a + 1) * b);
    128 define void @not_dominate(i1 %cond, i32 %a, i32 %b) {
    129 ; CHECK-LABEL: @not_dominate(
    130 entry:
    131   %a1 = add i32 %a, 1
    132   br i1 %cond, label %then, label %merge
    133 
    134 then:
    135   %mul0 = mul i32 %a, %b
    136 ; CHECK: %mul0 = mul i32 %a, %b
    137   call void @foo(i32 %mul0)
    138   br label %merge
    139 
    140 merge:
    141   %mul1 = mul i32 %a1, %b
    142 ; CHECK: %mul1 = mul i32 %a1, %b
    143   call void @foo(i32 %mul1)
    144   ret void
    145 }
    146 
    147 declare void @foo(i32)
    148