Skip to content

Commit

Permalink
[LoopIdiom] 'logical right shift until zero': the value must be loop-…
Browse files Browse the repository at this point in the history
…invariant

As per the reproducer provided by Mikael Holmén in post-commit review.
  • Loading branch information
LebedevRI authored and arichardson committed Sep 12, 2021
2 parents f94dd0b + aa3dac9 commit 865ed50
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2465,8 +2465,9 @@ static bool detectShiftUntilZeroIdiom(Loop *CurLoop, ScalarEvolution *SE,
}

// Step 2: Check if the comparison's operand is in desirable form.

if (!match(ValShifted, m_LShr(m_Value(Val), m_Instruction(NBits)))) {
// FIXME: Val could be a one-input PHI node, which we should look past.
if (!match(ValShifted, m_LShr(m_LoopInvariant(m_Value(Val), CurLoop),
m_Instruction(NBits)))) {
LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad comparisons value computation.\n");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,55 @@ end:
ret i8 %iv.res
}

define i8 @n26(i8 %start, i8 %extraoffset) {
; CHECK-LABEL: @n26(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
; CHECK-NEXT: [[VAL:%.*]] = call i8 @gen.i8()
; CHECK-NEXT: [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
; CHECK-NEXT: [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
; CHECK-NEXT: call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
; CHECK-NEXT: br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
; CHECK: end:
; CHECK-NEXT: [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
; CHECK-NEXT: [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
; CHECK-NEXT: [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
; CHECK-NEXT: [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
; CHECK-NEXT: call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
; CHECK-NEXT: ret i8 [[IV_RES]]
;
entry:
br label %loop

loop:
%iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
%nbits = add nsw i8 %iv, %extraoffset
%val = call i8 @gen.i8()
%val.shifted = lshr i8 %val, %nbits
%val.shifted.iszero = icmp eq i8 %val.shifted, 0
%iv.next = add i8 %iv, 1

call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)

br i1 %val.shifted.iszero, label %end, label %loop

end:
%iv.res = phi i8 [ %iv, %loop ]
%nbits.res = phi i8 [ %nbits, %loop ]
%val.shifted.res = phi i8 [ %val.shifted, %loop ]
%val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
%iv.next.res = phi i8 [ %iv.next, %loop ]

call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)

ret i8 %iv.res
}

; Tests with some small bit widths
declare void @escape_inner.i1(i1, i1, i1, i1, i1)
declare void @escape_outer.i1(i1, i1, i1, i1, i1)
Expand Down

0 comments on commit 865ed50

Please sign in to comment.