forked from OSchip/llvm-project
[LoopIdiomRecognize] Add a test case showing that we transform to ctpop without fully checking the 'x & (x-1)' part.
The code fails to check that the same value is used twice. We only make sure the left hand side of the and is part of the loop recurrence. The 'x' in the subtract can be any value. llvm-svn: 331436
This commit is contained in:
parent
21e77037c0
commit
a0cba89f86
|
@ -138,3 +138,49 @@ while.end: ; preds = %while.body, %entry
|
|||
%c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
|
||||
ret i32 %c.0.lcssa
|
||||
}
|
||||
|
||||
; The a & (a - 1) in the loop is a & (b - 1) in this code.
|
||||
; FIXME: We shouldn't emit ctpop for this.
|
||||
define i32 @popcount_bad(i64 %a, i64 %b) nounwind uwtable readnone ssp {
|
||||
; CHECK-LABEL: @popcount_bad(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
|
||||
; CHECK: while.body.preheader:
|
||||
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
; CHECK: while.body:
|
||||
; CHECK-NEXT: [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
|
||||
; CHECK-NEXT: [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
|
||||
; CHECK-NEXT: [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
|
||||
; CHECK-NEXT: [[INC]] = add nsw i32 [[C_05]], 1
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add i64 [[B:%.*]], -1
|
||||
; CHECK-NEXT: [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
|
||||
; CHECK-NEXT: [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
|
||||
; CHECK-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
|
||||
; CHECK: while.end.loopexit:
|
||||
; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
|
||||
; CHECK-NEXT: br label [[WHILE_END]]
|
||||
; CHECK: while.end:
|
||||
; CHECK-NEXT: [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
|
||||
; CHECK-NEXT: ret i32 [[C_0_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
%tobool3 = icmp eq i64 %a, 0
|
||||
br i1 %tobool3, label %while.end, label %while.body
|
||||
|
||||
while.body: ; preds = %entry, %while.body
|
||||
%c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
|
||||
%a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ]
|
||||
%inc = add nsw i32 %c.05, 1
|
||||
%sub = add i64 %b, -1
|
||||
%and = and i64 %sub, %a.addr.04
|
||||
%tobool = icmp eq i64 %and, 0
|
||||
br i1 %tobool, label %while.end, label %while.body
|
||||
|
||||
while.end: ; preds = %while.body, %entry
|
||||
%c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
|
||||
ret i32 %c.0.lcssa
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue