1f24f09d2SCraig Topper; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*48c6b272SRoman Lebedev; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbb -S < %s | FileCheck %s --check-prefixes=CPOP 3*48c6b272SRoman Lebedev; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbb -S < %s | FileCheck %s --check-prefixes=CPOP 4*48c6b272SRoman Lebedev; RUN: opt -passes=loop-idiom -mtriple=riscv32 -S < %s | FileCheck %s --check-prefixes=NOCPOP 5*48c6b272SRoman Lebedev; RUN: opt -passes=loop-idiom -mtriple=riscv64 -S < %s | FileCheck %s --check-prefixes=NOCPOP 6f24f09d2SCraig Topper 7f24f09d2SCraig Topper; Mostly copied from AMDGPU version. 8f24f09d2SCraig Topper 9f24f09d2SCraig Topper;To recognize this pattern: 10f24f09d2SCraig Topper;int popcount(unsigned long long a) { 11f24f09d2SCraig Topper; int c = 0; 12f24f09d2SCraig Topper; while (a) { 13f24f09d2SCraig Topper; c++; 14f24f09d2SCraig Topper; a &= a - 1; 15f24f09d2SCraig Topper; } 16f24f09d2SCraig Topper; return c; 17f24f09d2SCraig Topper;} 18f24f09d2SCraig Topper; 19f24f09d2SCraig Topper 20f24f09d2SCraig Topperdefine i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp { 21f24f09d2SCraig Topper; CPOP-LABEL: @popcount_i64( 22f24f09d2SCraig Topper; CPOP-NEXT: entry: 23f24f09d2SCraig Topper; CPOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]]) 24f24f09d2SCraig Topper; CPOP-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 25f24f09d2SCraig Topper; CPOP-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 26f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 27f24f09d2SCraig Topper; CPOP: while.body.preheader: 28f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_BODY:%.*]] 29f24f09d2SCraig Topper; CPOP: while.body: 30f24f09d2SCraig Topper; CPOP-NEXT: [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ] 31f24f09d2SCraig Topper; CPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 32f24f09d2SCraig Topper; CPOP-NEXT: [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 33f24f09d2SCraig Topper; CPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 34f24f09d2SCraig Topper; CPOP-NEXT: [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1 35f24f09d2SCraig Topper; CPOP-NEXT: [[AND]] = and i64 [[SUB]], [[A_ADDR_04]] 36f24f09d2SCraig Topper; CPOP-NEXT: [[TCDEC]] = sub nsw i32 [[TCPHI]], 1 37f24f09d2SCraig Topper; CPOP-NEXT: [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0 38f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 39f24f09d2SCraig Topper; CPOP: while.end.loopexit: 40f24f09d2SCraig Topper; CPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ] 41f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_END]] 42f24f09d2SCraig Topper; CPOP: while.end: 43f24f09d2SCraig Topper; CPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 44f24f09d2SCraig Topper; CPOP-NEXT: ret i32 [[C_0_LCSSA]] 45f24f09d2SCraig Topper; 46f24f09d2SCraig Topper; NOCPOP-LABEL: @popcount_i64( 47f24f09d2SCraig Topper; NOCPOP-NEXT: entry: 48f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0 49f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 50f24f09d2SCraig Topper; NOCPOP: while.body.preheader: 51f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_BODY:%.*]] 52f24f09d2SCraig Topper; NOCPOP: while.body: 53f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 54f24f09d2SCraig Topper; NOCPOP-NEXT: [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 55f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 56f24f09d2SCraig Topper; NOCPOP-NEXT: [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1 57f24f09d2SCraig Topper; NOCPOP-NEXT: [[AND]] = and i64 [[SUB]], [[A_ADDR_04]] 58f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 59f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 60f24f09d2SCraig Topper; NOCPOP: while.end.loopexit: 61f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ] 62f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_END]] 63f24f09d2SCraig Topper; NOCPOP: while.end: 64f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 65f24f09d2SCraig Topper; NOCPOP-NEXT: ret i32 [[C_0_LCSSA]] 66f24f09d2SCraig Topper; 67f24f09d2SCraig Topperentry: 68f24f09d2SCraig Topper %tobool3 = icmp eq i64 %a, 0 69f24f09d2SCraig Topper br i1 %tobool3, label %while.end, label %while.body 70f24f09d2SCraig Topper 71f24f09d2SCraig Topperwhile.body: ; preds = %entry, %while.body 72f24f09d2SCraig Topper %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 73f24f09d2SCraig Topper %a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ] 74f24f09d2SCraig Topper %inc = add nsw i32 %c.05, 1 75f24f09d2SCraig Topper %sub = add i64 %a.addr.04, -1 76f24f09d2SCraig Topper %and = and i64 %sub, %a.addr.04 77f24f09d2SCraig Topper %tobool = icmp eq i64 %and, 0 78f24f09d2SCraig Topper br i1 %tobool, label %while.end, label %while.body 79f24f09d2SCraig Topper 80f24f09d2SCraig Topperwhile.end: ; preds = %while.body, %entry 81f24f09d2SCraig Topper %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ] 82f24f09d2SCraig Topper ret i32 %c.0.lcssa 83f24f09d2SCraig Topper} 84f24f09d2SCraig Topper 85f24f09d2SCraig Topperdefine i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp { 86f24f09d2SCraig Topper; CPOP-LABEL: @popcount_i32( 87f24f09d2SCraig Topper; CPOP-NEXT: entry: 88f24f09d2SCraig Topper; CPOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]]) 89f24f09d2SCraig Topper; CPOP-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 90f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TMP1]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 91f24f09d2SCraig Topper; CPOP: while.body.preheader: 92f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_BODY:%.*]] 93f24f09d2SCraig Topper; CPOP: while.body: 94f24f09d2SCraig Topper; CPOP-NEXT: [[TCPHI:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ] 95f24f09d2SCraig Topper; CPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 96f24f09d2SCraig Topper; CPOP-NEXT: [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 97f24f09d2SCraig Topper; CPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 98f24f09d2SCraig Topper; CPOP-NEXT: [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1 99f24f09d2SCraig Topper; CPOP-NEXT: [[AND]] = and i32 [[SUB]], [[A_ADDR_04]] 100f24f09d2SCraig Topper; CPOP-NEXT: [[TCDEC]] = sub nsw i32 [[TCPHI]], 1 101f24f09d2SCraig Topper; CPOP-NEXT: [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0 102f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 103f24f09d2SCraig Topper; CPOP: while.end.loopexit: 104f24f09d2SCraig Topper; CPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY]] ] 105f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_END]] 106f24f09d2SCraig Topper; CPOP: while.end: 107f24f09d2SCraig Topper; CPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 108f24f09d2SCraig Topper; CPOP-NEXT: ret i32 [[C_0_LCSSA]] 109f24f09d2SCraig Topper; 110f24f09d2SCraig Topper; NOCPOP-LABEL: @popcount_i32( 111f24f09d2SCraig Topper; NOCPOP-NEXT: entry: 112f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0 113f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 114f24f09d2SCraig Topper; NOCPOP: while.body.preheader: 115f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_BODY:%.*]] 116f24f09d2SCraig Topper; NOCPOP: while.body: 117f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 118f24f09d2SCraig Topper; NOCPOP-NEXT: [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 119f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 120f24f09d2SCraig Topper; NOCPOP-NEXT: [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1 121f24f09d2SCraig Topper; NOCPOP-NEXT: [[AND]] = and i32 [[SUB]], [[A_ADDR_04]] 122f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0 123f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 124f24f09d2SCraig Topper; NOCPOP: while.end.loopexit: 125f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ] 126f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_END]] 127f24f09d2SCraig Topper; NOCPOP: while.end: 128f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 129f24f09d2SCraig Topper; NOCPOP-NEXT: ret i32 [[C_0_LCSSA]] 130f24f09d2SCraig Topper; 131f24f09d2SCraig Topperentry: 132f24f09d2SCraig Topper %tobool3 = icmp eq i32 %a, 0 133f24f09d2SCraig Topper br i1 %tobool3, label %while.end, label %while.body 134f24f09d2SCraig Topper 135f24f09d2SCraig Topperwhile.body: ; preds = %entry, %while.body 136f24f09d2SCraig Topper %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 137f24f09d2SCraig Topper %a.addr.04 = phi i32 [ %and, %while.body ], [ %a, %entry ] 138f24f09d2SCraig Topper %inc = add nsw i32 %c.05, 1 139f24f09d2SCraig Topper %sub = add i32 %a.addr.04, -1 140f24f09d2SCraig Topper %and = and i32 %sub, %a.addr.04 141f24f09d2SCraig Topper %tobool = icmp eq i32 %and, 0 142f24f09d2SCraig Topper br i1 %tobool, label %while.end, label %while.body 143f24f09d2SCraig Topper 144f24f09d2SCraig Topperwhile.end: ; preds = %while.body, %entry 145f24f09d2SCraig Topper %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ] 146f24f09d2SCraig Topper ret i32 %c.0.lcssa 147f24f09d2SCraig Topper} 148f24f09d2SCraig Topper 149f24f09d2SCraig Topperdefine i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp { 150f24f09d2SCraig Topper; CPOP-LABEL: @popcount_i128( 151f24f09d2SCraig Topper; CPOP-NEXT: entry: 152f24f09d2SCraig Topper; CPOP-NEXT: [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]]) 153f24f09d2SCraig Topper; CPOP-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32 154f24f09d2SCraig Topper; CPOP-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 155f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 156f24f09d2SCraig Topper; CPOP: while.body.preheader: 157f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_BODY:%.*]] 158f24f09d2SCraig Topper; CPOP: while.body: 159f24f09d2SCraig Topper; CPOP-NEXT: [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ] 160f24f09d2SCraig Topper; CPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 161f24f09d2SCraig Topper; CPOP-NEXT: [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 162f24f09d2SCraig Topper; CPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 163f24f09d2SCraig Topper; CPOP-NEXT: [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1 164f24f09d2SCraig Topper; CPOP-NEXT: [[AND]] = and i128 [[SUB]], [[A_ADDR_04]] 165f24f09d2SCraig Topper; CPOP-NEXT: [[TCDEC]] = sub nsw i32 [[TCPHI]], 1 166f24f09d2SCraig Topper; CPOP-NEXT: [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0 167f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 168f24f09d2SCraig Topper; CPOP: while.end.loopexit: 169f24f09d2SCraig Topper; CPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ] 170f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_END]] 171f24f09d2SCraig Topper; CPOP: while.end: 172f24f09d2SCraig Topper; CPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 173f24f09d2SCraig Topper; CPOP-NEXT: ret i32 [[C_0_LCSSA]] 174f24f09d2SCraig Topper; 175f24f09d2SCraig Topper; NOCPOP-LABEL: @popcount_i128( 176f24f09d2SCraig Topper; NOCPOP-NEXT: entry: 177f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0 178f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 179f24f09d2SCraig Topper; NOCPOP: while.body.preheader: 180f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_BODY:%.*]] 181f24f09d2SCraig Topper; NOCPOP: while.body: 182f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 183f24f09d2SCraig Topper; NOCPOP-NEXT: [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 184f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC]] = add nsw i32 [[C_05]], 1 185f24f09d2SCraig Topper; NOCPOP-NEXT: [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1 186f24f09d2SCraig Topper; NOCPOP-NEXT: [[AND]] = and i128 [[SUB]], [[A_ADDR_04]] 187f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0 188f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 189f24f09d2SCraig Topper; NOCPOP: while.end.loopexit: 190f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ] 191f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_END]] 192f24f09d2SCraig Topper; NOCPOP: while.end: 193f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 194f24f09d2SCraig Topper; NOCPOP-NEXT: ret i32 [[C_0_LCSSA]] 195f24f09d2SCraig Topper; 196f24f09d2SCraig Topperentry: 197f24f09d2SCraig Topper %tobool3 = icmp eq i128 %a, 0 198f24f09d2SCraig Topper br i1 %tobool3, label %while.end, label %while.body 199f24f09d2SCraig Topper 200f24f09d2SCraig Topperwhile.body: ; preds = %entry, %while.body 201f24f09d2SCraig Topper %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 202f24f09d2SCraig Topper %a.addr.04 = phi i128 [ %and, %while.body ], [ %a, %entry ] 203f24f09d2SCraig Topper %inc = add nsw i32 %c.05, 1 204f24f09d2SCraig Topper %sub = add i128 %a.addr.04, -1 205f24f09d2SCraig Topper %and = and i128 %sub, %a.addr.04 206f24f09d2SCraig Topper %tobool = icmp eq i128 %and, 0 207f24f09d2SCraig Topper br i1 %tobool, label %while.end, label %while.body 208f24f09d2SCraig Topper 209f24f09d2SCraig Topperwhile.end: ; preds = %while.body, %entry 210f24f09d2SCraig Topper %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ] 211f24f09d2SCraig Topper ret i32 %c.0.lcssa 212f24f09d2SCraig Topper} 213f24f09d2SCraig Topper 214f24f09d2SCraig Topper; To recognize this pattern: 215f24f09d2SCraig Topper;int popcount(unsigned long long a, int mydata1, int mydata2) { 216f24f09d2SCraig Topper; int c = 0; 217f24f09d2SCraig Topper; while (a) { 218f24f09d2SCraig Topper; c++; 219f24f09d2SCraig Topper; a &= a - 1; 220f24f09d2SCraig Topper; mydata1 *= c; 221f24f09d2SCraig Topper; mydata2 *= (int)a; 222f24f09d2SCraig Topper; } 223f24f09d2SCraig Topper; return c + mydata1 + mydata2; 224f24f09d2SCraig Topper;} 225f24f09d2SCraig Topper 226f24f09d2SCraig Topperdefine i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp { 227f24f09d2SCraig Topper; CPOP-LABEL: @popcount2( 228f24f09d2SCraig Topper; CPOP-NEXT: entry: 229f24f09d2SCraig Topper; CPOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]]) 230f24f09d2SCraig Topper; CPOP-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 231f24f09d2SCraig Topper; CPOP-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 232f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 233f24f09d2SCraig Topper; CPOP: while.body.preheader: 234f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_BODY:%.*]] 235f24f09d2SCraig Topper; CPOP: while.body: 236f24f09d2SCraig Topper; CPOP-NEXT: [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ] 237f24f09d2SCraig Topper; CPOP-NEXT: [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 238f24f09d2SCraig Topper; CPOP-NEXT: [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ] 239f24f09d2SCraig Topper; CPOP-NEXT: [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ] 240f24f09d2SCraig Topper; CPOP-NEXT: [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 241f24f09d2SCraig Topper; CPOP-NEXT: [[INC]] = add nsw i32 [[C_013]], 1 242f24f09d2SCraig Topper; CPOP-NEXT: [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1 243f24f09d2SCraig Topper; CPOP-NEXT: [[AND]] = and i64 [[SUB]], [[A_ADDR_010]] 244f24f09d2SCraig Topper; CPOP-NEXT: [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]] 245f24f09d2SCraig Topper; CPOP-NEXT: [[CONV:%.*]] = trunc i64 [[AND]] to i32 246f24f09d2SCraig Topper; CPOP-NEXT: [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]] 247f24f09d2SCraig Topper; CPOP-NEXT: [[TCDEC]] = sub nsw i32 [[TCPHI]], 1 248f24f09d2SCraig Topper; CPOP-NEXT: [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0 249f24f09d2SCraig Topper; CPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 250f24f09d2SCraig Topper; CPOP: while.end.loopexit: 251f24f09d2SCraig Topper; CPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ] 252f24f09d2SCraig Topper; CPOP-NEXT: [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ] 253f24f09d2SCraig Topper; CPOP-NEXT: [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ] 254f24f09d2SCraig Topper; CPOP-NEXT: br label [[WHILE_END]] 255f24f09d2SCraig Topper; CPOP: while.end: 256f24f09d2SCraig Topper; CPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 257f24f09d2SCraig Topper; CPOP-NEXT: [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 258f24f09d2SCraig Topper; CPOP-NEXT: [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 259f24f09d2SCraig Topper; CPOP-NEXT: [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]] 260f24f09d2SCraig Topper; CPOP-NEXT: [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]] 261f24f09d2SCraig Topper; CPOP-NEXT: ret i32 [[ADD2]] 262f24f09d2SCraig Topper; 263f24f09d2SCraig Topper; NOCPOP-LABEL: @popcount2( 264f24f09d2SCraig Topper; NOCPOP-NEXT: entry: 265f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0 266f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] 267f24f09d2SCraig Topper; NOCPOP: while.body.preheader: 268f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_BODY:%.*]] 269f24f09d2SCraig Topper; NOCPOP: while.body: 270f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ] 271f24f09d2SCraig Topper; NOCPOP-NEXT: [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ] 272f24f09d2SCraig Topper; NOCPOP-NEXT: [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ] 273f24f09d2SCraig Topper; NOCPOP-NEXT: [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ] 274f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC]] = add nsw i32 [[C_013]], 1 275f24f09d2SCraig Topper; NOCPOP-NEXT: [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1 276f24f09d2SCraig Topper; NOCPOP-NEXT: [[AND]] = and i64 [[SUB]], [[A_ADDR_010]] 277f24f09d2SCraig Topper; NOCPOP-NEXT: [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]] 278f24f09d2SCraig Topper; NOCPOP-NEXT: [[CONV:%.*]] = trunc i64 [[AND]] to i32 279f24f09d2SCraig Topper; NOCPOP-NEXT: [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]] 280f24f09d2SCraig Topper; NOCPOP-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 281f24f09d2SCraig Topper; NOCPOP-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]] 282f24f09d2SCraig Topper; NOCPOP: while.end.loopexit: 283f24f09d2SCraig Topper; NOCPOP-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ] 284f24f09d2SCraig Topper; NOCPOP-NEXT: [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ] 285f24f09d2SCraig Topper; NOCPOP-NEXT: [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ] 286f24f09d2SCraig Topper; NOCPOP-NEXT: br label [[WHILE_END]] 287f24f09d2SCraig Topper; NOCPOP: while.end: 288f24f09d2SCraig Topper; NOCPOP-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 289f24f09d2SCraig Topper; NOCPOP-NEXT: [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 290f24f09d2SCraig Topper; NOCPOP-NEXT: [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ] 291f24f09d2SCraig Topper; NOCPOP-NEXT: [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]] 292f24f09d2SCraig Topper; NOCPOP-NEXT: [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]] 293f24f09d2SCraig Topper; NOCPOP-NEXT: ret i32 [[ADD2]] 294f24f09d2SCraig Topper; 295f24f09d2SCraig Topperentry: 296f24f09d2SCraig Topper %tobool9 = icmp eq i64 %a, 0 297f24f09d2SCraig Topper br i1 %tobool9, label %while.end, label %while.body 298f24f09d2SCraig Topper 299f24f09d2SCraig Topperwhile.body: ; preds = %entry, %while.body 300f24f09d2SCraig Topper %c.013 = phi i32 [ %inc, %while.body ], [ 0, %entry ] 301f24f09d2SCraig Topper %mydata2.addr.012 = phi i32 [ %mul1, %while.body ], [ %mydata2, %entry ] 302f24f09d2SCraig Topper %mydata1.addr.011 = phi i32 [ %mul, %while.body ], [ %mydata1, %entry ] 303f24f09d2SCraig Topper %a.addr.010 = phi i64 [ %and, %while.body ], [ %a, %entry ] 304f24f09d2SCraig Topper %inc = add nsw i32 %c.013, 1 305f24f09d2SCraig Topper %sub = add i64 %a.addr.010, -1 306f24f09d2SCraig Topper %and = and i64 %sub, %a.addr.010 307f24f09d2SCraig Topper %mul = mul nsw i32 %inc, %mydata1.addr.011 308f24f09d2SCraig Topper %conv = trunc i64 %and to i32 309f24f09d2SCraig Topper %mul1 = mul nsw i32 %conv, %mydata2.addr.012 310f24f09d2SCraig Topper %tobool = icmp eq i64 %and, 0 311f24f09d2SCraig Topper br i1 %tobool, label %while.end, label %while.body 312f24f09d2SCraig Topper 313f24f09d2SCraig Topperwhile.end: ; preds = %while.body, %entry 314f24f09d2SCraig Topper %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ] 315f24f09d2SCraig Topper %mydata2.addr.0.lcssa = phi i32 [ %mydata2, %entry ], [ %mul1, %while.body ] 316f24f09d2SCraig Topper %mydata1.addr.0.lcssa = phi i32 [ %mydata1, %entry ], [ %mul, %while.body ] 317f24f09d2SCraig Topper %add = add i32 %mydata2.addr.0.lcssa, %mydata1.addr.0.lcssa 318f24f09d2SCraig Topper %add2 = add i32 %add, %c.0.lcssa 319f24f09d2SCraig Topper ret i32 %add2 320f24f09d2SCraig Topper} 321