From: Chad Rosier Date: Tue, 29 Sep 2015 18:26:15 +0000 (+0000) Subject: [AArch64] Add integer pre- and post-index halfword/byte loads and stores. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=16ec5ad2acc312dd52dda28a3d4df26480ed96be;p=oota-llvm.git [AArch64] Add integer pre- and post-index halfword/byte loads and stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248817 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp index d767c9ec805..b3ff11d86c1 100644 --- a/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ b/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -168,7 +168,13 @@ static bool isUnscaledLdSt(MachineInstr *MI) { static int getMemScale(MachineInstr *MI) { switch (MI->getOpcode()) { default: - llvm_unreachable("Opcode has unknown size!"); + llvm_unreachable("Opcode has unknown scale!"); + case AArch64::LDRBBui: + case AArch64::STRBBui: + return 1; + case AArch64::LDRHHui: + case AArch64::STRHHui: + return 2; case AArch64::LDRSui: case AArch64::LDURSi: case AArch64::LDRSWui: @@ -294,6 +300,10 @@ static unsigned getPreIndexedOpcode(unsigned Opc) { return AArch64::STRDpre; case AArch64::STRQui: return AArch64::STRQpre; + case AArch64::STRBBui: + return AArch64::STRBBpre; + case AArch64::STRHHui: + return AArch64::STRHHpre; case AArch64::STRWui: return AArch64::STRWpre; case AArch64::STRXui: @@ -304,6 +314,10 @@ static unsigned getPreIndexedOpcode(unsigned Opc) { return AArch64::LDRDpre; case AArch64::LDRQui: return AArch64::LDRQpre; + case AArch64::LDRBBui: + return AArch64::LDRBBpre; + case AArch64::LDRHHui: + return AArch64::LDRHHpre; case AArch64::LDRWui: return AArch64::LDRWpre; case AArch64::LDRXui: @@ -343,6 +357,10 @@ static unsigned getPostIndexedOpcode(unsigned Opc) { return AArch64::STRDpost; case AArch64::STRQui: return AArch64::STRQpost; + case AArch64::STRBBui: + return AArch64::STRBBpost; + case AArch64::STRHHui: + return AArch64::STRHHpost; case AArch64::STRWui: return AArch64::STRWpost; case AArch64::STRXui: @@ -353,6 +371,10 @@ static unsigned getPostIndexedOpcode(unsigned Opc) { return AArch64::LDRDpost; case AArch64::LDRQui: return AArch64::LDRQpost; + case AArch64::LDRBBui: + return AArch64::LDRBBpost; + case AArch64::LDRHHui: + return AArch64::LDRHHpost; case AArch64::LDRWui: return AArch64::LDRWpost; case AArch64::LDRXui: @@ -1083,11 +1105,15 @@ bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) { case AArch64::STRQui: case AArch64::STRXui: case AArch64::STRWui: + case AArch64::STRHHui: + case AArch64::STRBBui: case AArch64::LDRSui: case AArch64::LDRDui: case AArch64::LDRQui: case AArch64::LDRXui: case AArch64::LDRWui: + case AArch64::LDRHHui: + case AArch64::LDRBBui: // Unscaled instructions. case AArch64::STURSi: case AArch64::STURDi: diff --git a/test/CodeGen/AArch64/ldst-opt.ll b/test/CodeGen/AArch64/ldst-opt.ll index 56f3caaa408..bd0567c28b2 100644 --- a/test/CodeGen/AArch64/ldst-opt.ll +++ b/test/CodeGen/AArch64/ldst-opt.ll @@ -3,11 +3,15 @@ ; 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 } @@ -24,6 +28,62 @@ ; ; 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 { @@ -427,6 +487,54 @@ return: ; ; 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 @@ -557,6 +665,52 @@ exit: ; ; 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 @@ -672,6 +826,8 @@ exit: 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>)