[llvm] fded6f7 - [LoopUnroll] Add multi-exit test which does not exit through latch.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon May 17 09:09:03 PDT 2021


Author: Florian Hahn
Date: 2021-05-17T17:08:15+01:00
New Revision: fded6f77c357447b06b952f56c83d2a5487c5adf

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

LOG: [LoopUnroll] Add multi-exit test which does not exit through latch.

This patch adds a new test for loop-unrolling with multiple exiting
blocks, where the latch does not exit, but the header does. This can
happen when the loop has not been rotated, e.g. due to minsize.

Inspired by the following end-to-end test, using -Oz
https://godbolt.org/z/fP6sna8qK

    bool foo(int *ptr, int limit) {
        #pragma clang loop unroll(full)
        for (unsigned int i = 0; i < 4; i++) {
            if (ptr[i] > limit)
            return false;
            ptr[i]++;
        }
        return true;
    }

Added: 
    llvm/test/Transforms/LoopUnroll/unroll-header-exiting-with-phis-multiple-exiting-blocks.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/LoopUnroll/unroll-header-exiting-with-phis-multiple-exiting-blocks.ll b/llvm/test/Transforms/LoopUnroll/unroll-header-exiting-with-phis-multiple-exiting-blocks.ll
new file mode 100644
index 0000000000000..af224f06e1d19
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/unroll-header-exiting-with-phis-multiple-exiting-blocks.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -loop-unroll -S %s | FileCheck %s
+
+; Loop with multiple exiting blocks, where the header exits but not the latch,
+; e.g. because it has not been rotated.
+define i16 @full_unroll_multiple_exiting_blocks(i16* %A, i16 %x, i16 %y) {
+; CHECK-LABEL: @full_unroll_multiple_exiting_blocks(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[HEADER:%.*]]
+; CHECK:       header:
+; CHECK-NEXT:    [[RES:%.*]] = phi i16 [ 123, [[ENTRY:%.*]] ], [ [[RES_NEXT:%.*]], [[LATCH:%.*]] ]
+; CHECK-NEXT:    [[I_0:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INC9:%.*]], [[LATCH]] ]
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i16, i16* [[A:%.*]], i64 [[I_0]]
+; CHECK-NEXT:    [[LV:%.*]] = load i16, i16* [[PTR]], align 2
+; CHECK-NEXT:    [[RES_NEXT]] = add i16 [[RES]], [[LV]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[I_0]], 3
+; CHECK-NEXT:    br i1 [[CMP]], label [[EXITING_1:%.*]], label [[EXIT:%.*]]
+; CHECK:       exiting.1:
+; CHECK-NEXT:    [[EC_1:%.*]] = icmp eq i16 [[LV]], [[X:%.*]]
+; CHECK-NEXT:    br i1 [[EC_1]], label [[EXIT]], label [[EXITING_2:%.*]]
+; CHECK:       exiting.2:
+; CHECK-NEXT:    [[EC_2:%.*]] = icmp eq i16 [[LV]], [[Y:%.*]]
+; CHECK-NEXT:    br i1 [[EC_2]], label [[EXIT]], label [[LATCH]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[INC9]] = add i64 [[I_0]], 1
+; CHECK-NEXT:    br label [[HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[RES_LCSSA:%.*]] = phi i16 [ [[RES_NEXT]], [[HEADER]] ], [ 0, [[EXITING_1]] ], [ 1, [[EXITING_2]] ]
+; CHECK-NEXT:    ret i16 [[RES_LCSSA]]
+;
+entry:
+  br label %header
+
+header:
+  %res = phi i16 [ 123, %entry ], [ %res.next, %latch ]
+  %i.0 = phi i64 [ 0, %entry ], [ %inc9, %latch ]
+  %ptr = getelementptr inbounds i16, i16* %A, i64 %i.0
+  %lv = load i16, i16* %ptr
+  %res.next = add i16 %res, %lv
+  %cmp = icmp ult i64 %i.0, 3
+  br i1 %cmp, label %exiting.1, label %exit
+
+exiting.1:
+  %ec.1 = icmp eq i16 %lv, %x
+  br i1 %ec.1, label %exit, label %exiting.2
+
+exiting.2:
+  %ec.2 = icmp eq i16 %lv, %y
+  br i1 %ec.2, label %exit, label %latch
+
+latch:
+  %inc9 = add i64 %i.0, 1
+  br label %header
+
+exit:
+  %res.lcssa = phi i16 [ %res.next, %header ], [ 0, %exiting.1 ], [ 1, %exiting.2 ]
+  ret i16 %res.lcssa
+}


        


More information about the llvm-commits mailing list