[llvm] c98a8a0 - [HardwareLoops] Loop guard intrinsic to recognise zext

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 16 00:33:32 PDT 2021


Author: Sam Parker
Date: 2021-09-16T08:33:16+01:00
New Revision: c98a8a09b5eb04882dddd02346e5c3b4c90f038c

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

LOG: [HardwareLoops] Loop guard intrinsic to recognise zext

If a loop count was initially represented by a 32b unsigned int in C
then the hardware-loop pass can recognise the loop guard and insert
the llvm.test.set.loop.iterations intrinsic. If this was instead a
unsigned short/char then clang inserts a zext instruction to expand
the loop count to an i32. This patch adds the necessary pattern
matching to enable the use of lvm.test.set.loop.iterations in those
cases.

Patch by: sherwin-dc

Differential Revision: https://reviews.llvm.org/D109631

Added: 
    

Modified: 
    llvm/lib/CodeGen/HardwareLoops.cpp
    llvm/test/Transforms/HardwareLoops/loop-guards.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/HardwareLoops.cpp b/llvm/lib/CodeGen/HardwareLoops.cpp
index 248ef6c23974a..83b8c2d0eacbe 100644
--- a/llvm/lib/CodeGen/HardwareLoops.cpp
+++ b/llvm/lib/CodeGen/HardwareLoops.cpp
@@ -365,7 +365,13 @@ static bool CanGenerateTest(Loop *L, Value *Count) {
     return false;
   };
 
-  if (!IsCompareZero(ICmp, Count, 0) && !IsCompareZero(ICmp, Count, 1))
+  // Check if Count is a zext.
+  Value *CountBefZext =
+      isa<ZExtInst>(Count) ? cast<ZExtInst>(Count)->getOperand(0) : nullptr;
+
+  if (!IsCompareZero(ICmp, Count, 0) && !IsCompareZero(ICmp, Count, 1) &&
+      !IsCompareZero(ICmp, CountBefZext, 0) &&
+      !IsCompareZero(ICmp, CountBefZext, 1))
     return false;
 
   unsigned SuccIdx = ICmp->getPredicate() == ICmpInst::ICMP_NE ? 0 : 1;

diff  --git a/llvm/test/Transforms/HardwareLoops/loop-guards.ll b/llvm/test/Transforms/HardwareLoops/loop-guards.ll
index f1238616996ec..0c0b8e7e3a84b 100644
--- a/llvm/test/Transforms/HardwareLoops/loop-guards.ll
+++ b/llvm/test/Transforms/HardwareLoops/loop-guards.ll
@@ -348,3 +348,32 @@ do.body:
 if.end:                                           ; preds = %do.body, %entry
   ret void
 }
+
+; CHECK-LABEL: test12
+; CHECK: entry:
+; CHECK-EXIT:   [[TEST:%[^ ]+]] = call i1 @llvm.test.set.loop.iterations.i32(i32 %conv)
+; CHECK-LATCH:  [[TEST1:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %conv)
+; CHECK-LATCH:  [[TEST:%[^ ]+]] = extractvalue { i32, i1 } [[TEST1]], 1
+; CHECK:   br i1 [[TEST]], label %for.body.preheader, label %for.end
+; CHECK: for.body.preheader:
+; CHECK:   br label %for.body
+
+define void @test12(i32* nocapture %a, i32* nocapture readonly %b, i16 zeroext %length) {
+entry:
+  %conv = zext i16 %length to i32
+  %cmp8.not = icmp eq i16 %length, 0
+  br i1 %cmp8.not, label %for.end, label %for.body
+
+for.body:                                         ; preds = %entry, %for.body
+  %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+  %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.09
+  %0 = load i32, i32* %arrayidx, align 4
+  %arrayidx2 = getelementptr inbounds i32, i32* %a, i32 %i.09
+  store i32 %0, i32* %arrayidx2, align 4
+  %inc = add nuw nsw i32 %i.09, 1
+  %exitcond.not = icmp eq i32 %inc, %conv
+  br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end:                                          ; preds = %for.body, %entry
+  ret void
+}


        


More information about the llvm-commits mailing list