[llvm] aa3dac9 - [LoopIdiom] 'logical right shift until zero': the value must be loop-invariant

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon May 24 02:15:39 PDT 2021


Author: Roman Lebedev
Date: 2021-05-24T12:15:06+03:00
New Revision: aa3dac95edbfb892b6236341b431b222f7bd0926

URL: https://github.com/llvm/llvm-project/commit/aa3dac95edbfb892b6236341b431b222f7bd0926
DIFF: https://github.com/llvm/llvm-project/commit/aa3dac95edbfb892b6236341b431b222f7bd0926.diff

LOG: [LoopIdiom] 'logical right shift until zero': the value must be loop-invariant

As per the reproducer provided by Mikael Holmén in post-commit review.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
    llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 97c72f3bb812d..7d14c668fc435 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -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;
   }

diff  --git a/llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll b/llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll
index ed11afecf1cb0..1872b461e5aa8 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll
@@ -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)


        


More information about the llvm-commits mailing list