; This file contains tests for the AArch64 load/store optimizer.
%padding = type { i8*, i8*, i8*, i8* }
+%s.byte = type { i8, i8 }
+%s.halfword = type { i16, i16 }
%s.word = type { i32, i32 }
%s.doubleword = type { i64, i32 }
%s.quadword = type { fp128, i32 }
%s.float = type { float, i32 }
%s.double = type { double, i32 }
+%struct.byte = type { %padding, %s.byte }
+%struct.halfword = type { %padding, %s.halfword }
%struct.word = type { %padding, %s.word }
%struct.doubleword = type { %padding, %s.doubleword }
%struct.quadword = type { %padding, %s.quadword }
;
; with X being either w1, x1, s0, d0 or q0.
+declare void @bar_byte(%s.byte*, i8)
+
+define void @load-pre-indexed-byte(%struct.byte* %ptr) nounwind {
+; CHECK-LABEL: load-pre-indexed-byte
+; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
+entry:
+ %a = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1, i32 0
+ %add = load i8, i8* %a, align 4
+ br label %bar
+bar:
+ %c = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1
+ tail call void @bar_byte(%s.byte* %c, i8 %add)
+ ret void
+}
+
+define void @store-pre-indexed-byte(%struct.byte* %ptr, i8 %val) nounwind {
+; CHECK-LABEL: store-pre-indexed-byte
+; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
+entry:
+ %a = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1, i32 0
+ store i8 %val, i8* %a, align 4
+ br label %bar
+bar:
+ %c = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1
+ tail call void @bar_byte(%s.byte* %c, i8 %val)
+ ret void
+}
+
+declare void @bar_halfword(%s.halfword*, i16)
+
+define void @load-pre-indexed-halfword(%struct.halfword* %ptr) nounwind {
+; CHECK-LABEL: load-pre-indexed-halfword
+; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
+entry:
+ %a = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1, i32 0
+ %add = load i16, i16* %a, align 4
+ br label %bar
+bar:
+ %c = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1
+ tail call void @bar_halfword(%s.halfword* %c, i16 %add)
+ ret void
+}
+
+define void @store-pre-indexed-halfword(%struct.halfword* %ptr, i16 %val) nounwind {
+; CHECK-LABEL: store-pre-indexed-halfword
+; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
+entry:
+ %a = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1, i32 0
+ store i16 %val, i16* %a, align 4
+ br label %bar
+bar:
+ %c = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1
+ tail call void @bar_halfword(%s.halfword* %c, i16 %val)
+ ret void
+}
+
declare void @bar_word(%s.word*, i32)
define void @load-pre-indexed-word(%struct.word* %ptr) nounwind {
;
; with X being either w0, x0, s0, d0 or q0.
+define void @load-post-indexed-byte(i8* %array, i64 %count) nounwind {
+; CHECK-LABEL: load-post-indexed-byte
+; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}], #4
+entry:
+ %gep1 = getelementptr i8, i8* %array, i64 2
+ br label %body
+
+body:
+ %iv2 = phi i8* [ %gep3, %body ], [ %gep1, %entry ]
+ %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
+ %gep2 = getelementptr i8, i8* %iv2, i64 -1
+ %load = load i8, i8* %gep2
+ call void @use-byte(i8 %load)
+ %load2 = load i8, i8* %iv2
+ call void @use-byte(i8 %load2)
+ %iv.next = add i64 %iv, -4
+ %gep3 = getelementptr i8, i8* %iv2, i64 4
+ %cond = icmp eq i64 %iv.next, 0
+ br i1 %cond, label %exit, label %body
+
+exit:
+ ret void
+}
+
+define void @load-post-indexed-halfword(i16* %array, i64 %count) nounwind {
+; CHECK-LABEL: load-post-indexed-halfword
+; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}], #8
+entry:
+ %gep1 = getelementptr i16, i16* %array, i64 2
+ br label %body
+
+body:
+ %iv2 = phi i16* [ %gep3, %body ], [ %gep1, %entry ]
+ %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
+ %gep2 = getelementptr i16, i16* %iv2, i64 -1
+ %load = load i16, i16* %gep2
+ call void @use-halfword(i16 %load)
+ %load2 = load i16, i16* %iv2
+ call void @use-halfword(i16 %load2)
+ %iv.next = add i64 %iv, -4
+ %gep3 = getelementptr i16, i16* %iv2, i64 4
+ %cond = icmp eq i64 %iv.next, 0
+ br i1 %cond, label %exit, label %body
+
+exit:
+ ret void
+}
+
define void @load-post-indexed-word(i32* %array, i64 %count) nounwind {
; CHECK-LABEL: load-post-indexed-word
; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #16
;
; with X being either w0, x0, s0, d0 or q0.
+define void @store-post-indexed-byte(i8* %array, i64 %count, i8 %val) nounwind {
+; CHECK-LABEL: store-post-indexed-byte
+; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}], #4
+entry:
+ %gep1 = getelementptr i8, i8* %array, i64 2
+ br label %body
+
+body:
+ %iv2 = phi i8* [ %gep3, %body ], [ %gep1, %entry ]
+ %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
+ %gep2 = getelementptr i8, i8* %iv2, i64 -1
+ %load = load i8, i8* %gep2
+ call void @use-byte(i8 %load)
+ store i8 %val, i8* %iv2
+ %iv.next = add i64 %iv, -4
+ %gep3 = getelementptr i8, i8* %iv2, i64 4
+ %cond = icmp eq i64 %iv.next, 0
+ br i1 %cond, label %exit, label %body
+
+exit:
+ ret void
+}
+
+define void @store-post-indexed-halfword(i16* %array, i64 %count, i16 %val) nounwind {
+; CHECK-LABEL: store-post-indexed-halfword
+; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}], #8
+entry:
+ %gep1 = getelementptr i16, i16* %array, i64 2
+ br label %body
+
+body:
+ %iv2 = phi i16* [ %gep3, %body ], [ %gep1, %entry ]
+ %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
+ %gep2 = getelementptr i16, i16* %iv2, i64 -1
+ %load = load i16, i16* %gep2
+ call void @use-halfword(i16 %load)
+ store i16 %val, i16* %iv2
+ %iv.next = add i64 %iv, -4
+ %gep3 = getelementptr i16, i16* %iv2, i64 4
+ %cond = icmp eq i64 %iv.next, 0
+ br i1 %cond, label %exit, label %body
+
+exit:
+ ret void
+}
+
define void @store-post-indexed-word(i32* %array, i64 %count, i32 %val) nounwind {
; CHECK-LABEL: store-post-indexed-word
; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #16
ret void
}
+declare void @use-byte(i8)
+declare void @use-halfword(i16)
declare void @use-word(i32)
declare void @use-doubleword(i64)
declare void @use-quadword(<2 x i64>)