xref: /llvm-project/llvm/test/Transforms/LoopUnroll/full-unroll-invariant.ll (revision 5103ef64fe4f60cc0fd518b514c712f4b4c03d98)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -passes=loop-unroll -unroll-threshold=1 | FileCheck %s
3; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -unroll-threshold=1 | FileCheck %s
4
5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6
7; Body fully unrolls into a single instruction after unroll and simplify
8define i32 @test(i8 %a) {
9; CHECK-LABEL: @test(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
12; CHECK:       for.body:
13; CHECK-NEXT:    [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32
14; CHECK-NEXT:    ret i32 [[ZEXT_9]]
15;
16entry:
17  br label %for.body
18
19for.body:
20  %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ]
21  %zext = zext i8 %a to i32
22  %inc = add nuw nsw i64 %phi, 1
23  %cmp = icmp ult i64 %inc, 10
24  br i1 %cmp, label %for.body, label %for.exit
25
26for.exit:
27  ret i32 %zext
28}
29
30; Generalized version of previous to show benefit of using SCEV's ability
31; to prove invariance not Loop::isLoopInvaraint.
32define i32 @test2(i8 %a) {
33; CHECK-LABEL: @test2(
34; CHECK-NEXT:  entry:
35; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
36; CHECK:       for.body:
37; CHECK-NEXT:    [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32
38; CHECK-NEXT:    [[AND_9:%.*]] = and i32 [[ZEXT_9]], 31
39; CHECK-NEXT:    [[SHL_9:%.*]] = shl i32 [[AND_9]], 15
40; CHECK-NEXT:    ret i32 [[SHL_9]]
41;
42entry:
43  br label %for.body
44
45for.body:
46  %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ]
47  %zext = zext i8 %a to i32
48  %and = and i32 %zext, 31
49  %shl = shl i32 %and, 15
50  %inc = add nuw nsw i64 %phi, 1
51  %cmp = icmp ult i64 %inc, 10
52  br i1 %cmp, label %for.body, label %for.exit
53
54for.exit:
55  ret i32 %shl
56}
57
58; Show that this works for instructions which might fault as well
59define i32 @test3(i8 %a) {
60; CHECK-LABEL: @test3(
61; CHECK-NEXT:  entry:
62; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
63; CHECK:       for.body:
64; CHECK-NEXT:    [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32
65; CHECK-NEXT:    [[DIV_9:%.*]] = udiv i32 [[ZEXT_9]], 31
66; CHECK-NEXT:    ret i32 [[DIV_9]]
67;
68entry:
69  br label %for.body
70
71for.body:
72  %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ]
73  %zext = zext i8 %a to i32
74  %div = udiv i32 %zext, 31
75  %inc = add nuw nsw i64 %phi, 1
76  %cmp = icmp ult i64 %inc, 10
77  br i1 %cmp, label %for.body, label %for.exit
78
79for.exit:
80  ret i32 %div
81}
82