Home | History | Annotate | Download | only in AMDGPU
      1 ; RUN: opt -loop-idiom -mtriple=amdgcn-- -S < %s | FileCheck %s
      2 
      3 ; Mostly copied from x86 version.
      4 
      5 ;To recognize this pattern:
      6 ;int popcount(unsigned long long a) {
      7 ;    int c = 0;
      8 ;    while (a) {
      9 ;        c++;
     10 ;        a &= a - 1;
     11 ;    }
     12 ;    return c;
     13 ;}
     14 ;
     15 
     16 ; CHECK-LABEL: @popcount_i64
     17 ; CHECK: entry
     18 ; CHECK: llvm.ctpop.i64
     19 ; CHECK: ret
     20 define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
     21 entry:
     22   %tobool3 = icmp eq i64 %a, 0
     23   br i1 %tobool3, label %while.end, label %while.body
     24 
     25 while.body:                                       ; preds = %entry, %while.body
     26   %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
     27   %a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ]
     28   %inc = add nsw i32 %c.05, 1
     29   %sub = add i64 %a.addr.04, -1
     30   %and = and i64 %sub, %a.addr.04
     31   %tobool = icmp eq i64 %and, 0
     32   br i1 %tobool, label %while.end, label %while.body
     33 
     34 while.end:                                        ; preds = %while.body, %entry
     35   %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
     36   ret i32 %c.0.lcssa
     37 }
     38 
     39 ; CHECK-LABEL: @popcount_i32
     40 ; CHECK: entry
     41 ; CHECK: llvm.ctpop.i32
     42 ; CHECK: ret
     43 define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
     44 entry:
     45   %tobool3 = icmp eq i32 %a, 0
     46   br i1 %tobool3, label %while.end, label %while.body
     47 
     48 while.body:                                       ; preds = %entry, %while.body
     49   %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
     50   %a.addr.04 = phi i32 [ %and, %while.body ], [ %a, %entry ]
     51   %inc = add nsw i32 %c.05, 1
     52   %sub = add i32 %a.addr.04, -1
     53   %and = and i32 %sub, %a.addr.04
     54   %tobool = icmp eq i32 %and, 0
     55   br i1 %tobool, label %while.end, label %while.body
     56 
     57 while.end:                                        ; preds = %while.body, %entry
     58   %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
     59   ret i32 %c.0.lcssa
     60 }
     61 
     62 ; CHECK-LABEL: @popcount_i128
     63 ; CHECK: entry
     64 ; CHECK: llvm.ctpop.i128
     65 ; CHECK: ret
     66 define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
     67 entry:
     68   %tobool3 = icmp eq i128 %a, 0
     69   br i1 %tobool3, label %while.end, label %while.body
     70 
     71 while.body:                                       ; preds = %entry, %while.body
     72   %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
     73   %a.addr.04 = phi i128 [ %and, %while.body ], [ %a, %entry ]
     74   %inc = add nsw i32 %c.05, 1
     75   %sub = add i128 %a.addr.04, -1
     76   %and = and i128 %sub, %a.addr.04
     77   %tobool = icmp eq i128 %and, 0
     78   br i1 %tobool, label %while.end, label %while.body
     79 
     80 while.end:                                        ; preds = %while.body, %entry
     81   %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
     82   ret i32 %c.0.lcssa
     83 }
     84 
     85 ; To recognize this pattern:
     86 ;int popcount(unsigned long long a, int mydata1, int mydata2) {
     87 ;    int c = 0;
     88 ;    while (a) {
     89 ;        c++;
     90 ;        a &= a - 1;
     91 ;        mydata1 *= c;
     92 ;        mydata2 *= (int)a;
     93 ;    }
     94 ;    return c + mydata1 + mydata2;
     95 ;}
     96 
     97 ; CHECK-LABEL: @popcount2
     98 ; CHECK: entry
     99 ; CHECK: llvm.ctpop.i64
    100 ; CHECK: ret
    101 define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
    102 entry:
    103   %tobool9 = icmp eq i64 %a, 0
    104   br i1 %tobool9, label %while.end, label %while.body
    105 
    106 while.body:                                       ; preds = %entry, %while.body
    107   %c.013 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
    108   %mydata2.addr.012 = phi i32 [ %mul1, %while.body ], [ %mydata2, %entry ]
    109   %mydata1.addr.011 = phi i32 [ %mul, %while.body ], [ %mydata1, %entry ]
    110   %a.addr.010 = phi i64 [ %and, %while.body ], [ %a, %entry ]
    111   %inc = add nsw i32 %c.013, 1
    112   %sub = add i64 %a.addr.010, -1
    113   %and = and i64 %sub, %a.addr.010
    114   %mul = mul nsw i32 %inc, %mydata1.addr.011
    115   %conv = trunc i64 %and to i32
    116   %mul1 = mul nsw i32 %conv, %mydata2.addr.012
    117   %tobool = icmp eq i64 %and, 0
    118   br i1 %tobool, label %while.end, label %while.body
    119 
    120 while.end:                                        ; preds = %while.body, %entry
    121   %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
    122   %mydata2.addr.0.lcssa = phi i32 [ %mydata2, %entry ], [ %mul1, %while.body ]
    123   %mydata1.addr.0.lcssa = phi i32 [ %mydata1, %entry ], [ %mul, %while.body ]
    124   %add = add i32 %mydata2.addr.0.lcssa, %mydata1.addr.0.lcssa
    125   %add2 = add i32 %add, %c.0.lcssa
    126   ret i32 %add2
    127 }
    128