[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Inline / noalias2.ll
blob58ef1cb88ce2c113c08d6d278a13a290f1deb494
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
3 ; RUN: opt -inline -enable-noalias-to-md-conversion --enable-knowledge-retention -S < %s | FileCheck %s
5 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
8 define void @hello(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 {
9 ; CHECK-LABEL: define {{[^@]+}}@hello
10 ; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) [[ATTR0:#.*]] {
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4
13 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
14 ; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX]], align 4
15 ; CHECK-NEXT:    ret void
17 entry:
18   %0 = load float, float* %c, align 4
19   %arrayidx = getelementptr inbounds float, float* %a, i64 5
20   store float %0, float* %arrayidx, align 4
21   ret void
24 define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 {
25 ; CHECK-LABEL: define {{[^@]+}}@foo
26 ; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) [[ATTR0]] {
27 ; CHECK-NEXT:  entry:
28 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !0)
29 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !3)
30 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !3, !noalias !0
31 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
32 ; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0, !noalias !3
33 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4
34 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
35 ; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX]], align 4
36 ; CHECK-NEXT:    ret void
38 entry:
39   tail call void @hello(float* %a, float* %c)
40   %0 = load float, float* %c, align 4
41   %arrayidx = getelementptr inbounds float, float* %a, i64 7
42   store float %0, float* %arrayidx, align 4
43   ret void
46 define void @hello2(float* noalias nocapture %a, float* noalias nocapture %b, float* nocapture readonly %c) #0 {
47 ; CHECK-LABEL: define {{[^@]+}}@hello2
48 ; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) [[ATTR0]] {
49 ; CHECK-NEXT:  entry:
50 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4
51 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
52 ; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX]], align 4
53 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
54 ; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX1]], align 4
55 ; CHECK-NEXT:    ret void
57 entry:
58   %0 = load float, float* %c, align 4
59   %arrayidx = getelementptr inbounds float, float* %a, i64 6
60   store float %0, float* %arrayidx, align 4
61   %arrayidx1 = getelementptr inbounds float, float* %b, i64 8
62   store float %0, float* %arrayidx1, align 4
63   ret void
66 ; Check that when hello() is inlined into foo(), and then foo() is inlined into
67 ; foo2(), the noalias scopes are properly concatenated.
68 define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
69 ; CHECK-LABEL: define {{[^@]+}}@foo2
70 ; CHECK-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) [[ATTR0]] {
71 ; CHECK-NEXT:  entry:
72 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !5)
73 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !8)
74 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !10) [[ATTR2:#.*]]
75 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !13) [[ATTR2]]
76 ; CHECK-NEXT:    [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !15, !noalias !16
77 ; CHECK-NEXT:    [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
78 ; CHECK-NEXT:    store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !16, !noalias !15
79 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !8, !noalias !5
80 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
81 ; CHECK-NEXT:    store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !5, !noalias !8
82 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !17)
83 ; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata !20)
84 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !22
85 ; CHECK-NEXT:    [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
86 ; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !17, !noalias !20
87 ; CHECK-NEXT:    [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
88 ; CHECK-NEXT:    store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !20, !noalias !17
89 ; CHECK-NEXT:    [[TMP3:%.*]] = load float, float* [[C]], align 4
90 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
91 ; CHECK-NEXT:    store float [[TMP3]], float* [[ARRAYIDX]], align 4
92 ; CHECK-NEXT:    ret void
94 entry:
95   tail call void @foo(float* %a, float* %c)
96   tail call void @hello2(float* %a, float* %b, float* %c)
97   %0 = load float, float* %c, align 4
98   %arrayidx = getelementptr inbounds float, float* %a, i64 7
99   store float %0, float* %arrayidx, align 4
100   ret void
103 ; CHECK: !0 = !{!1}
104 ; CHECK: !1 = distinct !{!1, !2, !"hello: %a"}
105 ; CHECK: !2 = distinct !{!2, !"hello"}
106 ; CHECK: !3 = !{!4}
107 ; CHECK: !4 = distinct !{!4, !2, !"hello: %c"}
108 ; CHECK: !5 = !{!6}
109 ; CHECK: !6 = distinct !{!6, !7, !"foo: %a"}
110 ; CHECK: !7 = distinct !{!7, !"foo"}
111 ; CHECK: !8 = !{!9}
112 ; CHECK: !9 = distinct !{!9, !7, !"foo: %c"}
113 ; CHECK: !10 = !{!11}
114 ; CHECK: !11 = distinct !{!11, !12, !"hello: %a"}
115 ; CHECK: !12 = distinct !{!12, !"hello"}
116 ; CHECK: !13 = !{!14}
117 ; CHECK: !14 = distinct !{!14, !12, !"hello: %c"}
118 ; CHECK: !15 = !{!14, !9}
119 ; CHECK: !16 = !{!11, !6}
120 ; CHECK: !17 = !{!18}
121 ; CHECK: !18 = distinct !{!18, !19, !"hello2: %a"}
122 ; CHECK: !19 = distinct !{!19, !"hello2"}
123 ; CHECK: !20 = !{!21}
124 ; CHECK: !21 = distinct !{!21, !19, !"hello2: %b"}
125 ; CHECK: !22 = !{!18, !21}
127 attributes #0 = { nounwind uwtable }