1 ; Check the memd loads are generated by HexagonLoadStoreWidening pass
2 ; Check that memw loads from adjacent memory location are replaced with memd,
3 ; though the load/stores alias with instructions that occur later in the block.
4 ; The order of memory operations remains unchanged.
6 ; RUN: llc -mtriple=hexagon -verify-machineinstrs < %s | FileCheck %s
8 target triple = "hexagon"
10 ; CHECK-LABEL: load_store_interleaved:
11 ; CHECK: r{{[0-9]+}}:{{[0-9]+}} = memd(r{{[0-9]+}}+#0)
12 ; CHECK: memd(r{{[0-9]+}}+#0) = r{{[0-9]+}}:{{[0-9]+}}
13 ; Function Attrs: mustprogress nounwind
14 define linkonce_odr dso_local void @load_store_interleaved(ptr %p, float %a, float %b) local_unnamed_addr {
16 %0 = load float, ptr %p, align 8
17 %add0 = fadd float %0, %a
18 store float %add0, ptr %p, align 8
19 %q = getelementptr i8, ptr %p, i32 4
20 %1 = load float, ptr %q, align 4
21 %add1 = fadd float %1, %b
22 store float %add1, ptr %q, align 4
26 ; Store can be widened here, but this order of instructions is not currently handled
27 ; CHECK-LABEL: loads_between_stores:
28 ; CHECK: r{{[0-9]+}}:{{[0-9]+}} = memd(r{{[0-9]+}}+#0)
29 ; CHECK-NOT: memd(r{{[0-9]+}}+#4) = r{{[0-9]+}}:{{[0-9]+}}
30 ; Function Attrs: mustprogress nounwind
31 define linkonce_odr dso_local void @loads_between_stores(ptr %p, float %a, float %b) local_unnamed_addr {
33 %add0 = fadd float %b, %a
34 %q = getelementptr i8, ptr %p, i32 4
35 %r = getelementptr i8, ptr %p, i32 8
36 store float %add0, ptr %r, align 4
37 %0 = load float, ptr %p, align 8
38 %1 = load float, ptr %q, align 4
39 %add1 = fadd float %1, %0
40 store float %add1, ptr %q, align 8
44 ; CHECK-LABEL: loads_before_stores:
45 ; CHECK: r{{[0-9]+}}:{{[0-9]+}} = memd(r{{[0-9]+}}+#0)
46 ; CHECK: memd(r{{[0-9]+}}+#0) = r{{[0-9]+}}:{{[0-9]+}}
47 ; Function Attrs: mustprogress nounwind
48 define linkonce_odr dso_local void @loads_before_stores(ptr %p, float %a, float %b) local_unnamed_addr {
50 %0 = load float, ptr %p, align 8
51 %q = getelementptr i8, ptr %p, i32 4
52 %1 = load float, ptr %q, align 4
53 %add0 = fadd float %0, %a
54 store float %add0, ptr %p, align 8
55 %add1 = fadd float %1, %b
56 store float %add1, ptr %q, align 4
60 ; Store can be widened here, but this order of instructions is not currently handled
61 ; CHECK-LABEL: store_load_interleaved:
62 ; CHECK: r{{[0-9]+}}:{{[0-9]+}} = memd(r{{[0-9]+}}+#0)
63 ; CHECK-NOT: memd(r{{[0-9]+}}+#0) = r{{[0-9]+}}:{{[0-9]+}}
64 ; Function Attrs: mustprogress nounwind
65 define linkonce_odr dso_local void @store_load_interleaved(ptr %p, float %a, float %b, float %f) local_unnamed_addr {
67 %q = getelementptr i8, ptr %p, i32 4
68 %r = getelementptr i8, ptr %p, i32 8
69 store float %f, ptr %r, align 4
70 %0 = load float, ptr %p, align 8
71 %add0 = fadd float %0, %a
72 store float %add0, ptr %p, align 8
73 %1 = load float, ptr %q, align 4
74 %add1 = fadd float %1, %b
75 %add2 = fadd float %add1, %add0
76 store float %add2, ptr %q, align 8
80 ; CHECK-LABEL: stores_between_loads:
81 ; CHECK-NOT: r{{[0-9]+}}:{{[0-9]+}} = memd(r{{[0-9]+}}+#0)
82 ; CHECK: memd(r{{[0-9]+}}+#0) = r{{[0-9]+}}:{{[0-9]+}}
83 ; Function Attrs: mustprogress nounwind
84 define linkonce_odr dso_local void @stores_between_loads(ptr %p, float %a, float %b, float %f) local_unnamed_addr {
86 %0 = load float, ptr %p, align 8
87 %add0 = fadd float %f, %0
88 store float %add0, ptr %p, align 8
89 %q = getelementptr i8, ptr %p, i32 4
90 %add1 = fadd float %f, %b
91 store float %add1, ptr %q, align 8
92 %r = getelementptr i8, ptr %p, i32 8
93 %1 = load float, ptr %r, align 4
94 %add2 = fadd float %add1, %1
95 store float %add2, ptr %r, align 4