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