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. 5 6; RUN: llc -mtriple=hexagon -verify-machineinstrs < %s | FileCheck %s 7 8target triple = "hexagon" 9 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 14define linkonce_odr dso_local void @load_store_interleaved(ptr %p, float %a, float %b) local_unnamed_addr { 15entry: 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 23 ret void 24} 25 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 31define linkonce_odr dso_local void @loads_between_stores(ptr %p, float %a, float %b) local_unnamed_addr { 32entry: 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 41 ret void 42} 43 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 48define linkonce_odr dso_local void @loads_before_stores(ptr %p, float %a, float %b) local_unnamed_addr { 49entry: 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 57 ret void 58} 59 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 65define linkonce_odr dso_local void @store_load_interleaved(ptr %p, float %a, float %b, float %f) local_unnamed_addr { 66entry: 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 77 ret void 78} 79 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 84define linkonce_odr dso_local void @stores_between_loads(ptr %p, float %a, float %b, float %f) local_unnamed_addr { 85entry: 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 96 ret void 97} 98