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