From 9ac20a1e1073cf8eb40d8efe42e17bd3b2be4682 Mon Sep 17 00:00:00 2001 From: Haicheng Wu Date: Thu, 22 Dec 2016 01:39:24 +0000 Subject: [PATCH] [AArch64] Correct the check of signed 9-bit imm in getIndexedAddressParts(). -256 is a legal indexed address part. Differential Revision: https://reviews.llvm.org/D27537 llvm-svn: 290296 --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 6 +- llvm/test/CodeGen/AArch64/arm64-indexed-memory.ll | 184 ++++++++++++++++++++++ 2 files changed, 188 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index c8200c2..4c98253 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -10272,8 +10272,10 @@ bool AArch64TargetLowering::getIndexedAddressParts(SDNode *Op, SDValue &Base, // All of the indexed addressing mode instructions take a signed // 9 bit immediate offset. if (ConstantSDNode *RHS = dyn_cast(Op->getOperand(1))) { - int64_t RHSC = (int64_t)RHS->getZExtValue(); - if (RHSC >= 256 || RHSC <= -256) + int64_t RHSC = RHS->getSExtValue(); + if (Op->getOpcode() == ISD::SUB) + RHSC = -(uint64_t)RHSC; + if (!isInt<9>(RHSC)) return false; IsInc = (Op->getOpcode() == ISD::ADD); Offset = Op->getOperand(1); diff --git a/llvm/test/CodeGen/AArch64/arm64-indexed-memory.ll b/llvm/test/CodeGen/AArch64/arm64-indexed-memory.ll index aff1fd8..f60fb34 100644 --- a/llvm/test/CodeGen/AArch64/arm64-indexed-memory.ll +++ b/llvm/test/CodeGen/AArch64/arm64-indexed-memory.ll @@ -11,6 +11,29 @@ define void @store64(i64** nocapture %out, i64 %index, i64 %spacing) nounwind no ret void } +define void @store64idxpos256(i64** nocapture %out, i64 %index, i64 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store64idxpos256: +; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256 +; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}] +; CHECK: ret + %tmp = load i64*, i64** %out, align 8 + %incdec.ptr = getelementptr inbounds i64, i64* %tmp, i64 32 + store i64 %spacing, i64* %tmp, align 4 + store i64* %incdec.ptr, i64** %out, align 8 + ret void +} + +define void @store64idxneg256(i64** nocapture %out, i64 %index, i64 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store64idxneg256: +; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #-256 +; CHECK: ret + %tmp = load i64*, i64** %out, align 8 + %incdec.ptr = getelementptr inbounds i64, i64* %tmp, i64 -32 + store i64 %spacing, i64* %tmp, align 4 + store i64* %incdec.ptr, i64** %out, align 8 + ret void +} + define void @store32(i32** nocapture %out, i32 %index, i32 %spacing) nounwind noinline ssp { ; CHECK-LABEL: store32: ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4 @@ -22,6 +45,29 @@ define void @store32(i32** nocapture %out, i32 %index, i32 %spacing) nounwind no ret void } +define void @store32idxpos256(i32** nocapture %out, i32 %index, i32 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store32idxpos256: +; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256 +; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}] +; CHECK: ret + %tmp = load i32*, i32** %out, align 8 + %incdec.ptr = getelementptr inbounds i32, i32* %tmp, i64 64 + store i32 %spacing, i32* %tmp, align 4 + store i32* %incdec.ptr, i32** %out, align 8 + ret void +} + +define void @store32idxneg256(i32** nocapture %out, i32 %index, i32 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store32idxneg256: +; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #-256 +; CHECK: ret + %tmp = load i32*, i32** %out, align 8 + %incdec.ptr = getelementptr inbounds i32, i32* %tmp, i64 -64 + store i32 %spacing, i32* %tmp, align 4 + store i32* %incdec.ptr, i32** %out, align 8 + ret void +} + define void @store16(i16** nocapture %out, i16 %index, i16 %spacing) nounwind noinline ssp { ; CHECK-LABEL: store16: ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2 @@ -33,6 +79,29 @@ define void @store16(i16** nocapture %out, i16 %index, i16 %spacing) nounwind no ret void } +define void @store16idxpos256(i16** nocapture %out, i16 %index, i16 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store16idxpos256: +; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256 +; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}] +; CHECK: ret + %tmp = load i16*, i16** %out, align 8 + %incdec.ptr = getelementptr inbounds i16, i16* %tmp, i64 128 + store i16 %spacing, i16* %tmp, align 4 + store i16* %incdec.ptr, i16** %out, align 8 + ret void +} + +define void @store16idxneg256(i16** nocapture %out, i16 %index, i16 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store16idxneg256: +; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #-256 +; CHECK: ret + %tmp = load i16*, i16** %out, align 8 + %incdec.ptr = getelementptr inbounds i16, i16* %tmp, i64 -128 + store i16 %spacing, i16* %tmp, align 4 + store i16* %incdec.ptr, i16** %out, align 8 + ret void +} + define void @store8(i8** nocapture %out, i8 %index, i8 %spacing) nounwind noinline ssp { ; CHECK-LABEL: store8: ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1 @@ -44,6 +113,29 @@ define void @store8(i8** nocapture %out, i8 %index, i8 %spacing) nounwind noinli ret void } +define void @store8idxpos256(i8** nocapture %out, i8 %index, i8 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store8idxpos256: +; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256 +; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}] +; CHECK: ret + %tmp = load i8*, i8** %out, align 8 + %incdec.ptr = getelementptr inbounds i8, i8* %tmp, i64 256 + store i8 %spacing, i8* %tmp, align 4 + store i8* %incdec.ptr, i8** %out, align 8 + ret void +} + +define void @store8idxneg256(i8** nocapture %out, i8 %index, i8 %spacing) nounwind noinline ssp { +; CHECK-LABEL: store8idxneg256: +; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #-256 +; CHECK: ret + %tmp = load i8*, i8** %out, align 8 + %incdec.ptr = getelementptr inbounds i8, i8* %tmp, i64 -256 + store i8 %spacing, i8* %tmp, align 4 + store i8* %incdec.ptr, i8** %out, align 8 + ret void +} + define void @truncst64to32(i32** nocapture %out, i32 %index, i64 %spacing) nounwind noinline ssp { ; CHECK-LABEL: truncst64to32: ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4 @@ -158,6 +250,29 @@ define i64 * @pre64(i64** nocapture %out, i64 %spacing) nounwind noinline ssp { ret i64 *%ptr } +define i64 * @pre64idxpos256(i64** nocapture %out, i64 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre64idxpos256: +; CHECK: ldr x{{[0-9+]}}, [x0] +; CHECK-NEXT: add x0, x{{[0-9+]}}, #256 +; CHECK-NEXT: str x1, [x{{[0-9+]}}, #256] +; CHECK-NEXT: ret + %tmp = load i64*, i64** %out, align 8 + %ptr = getelementptr inbounds i64, i64* %tmp, i64 32 + store i64 %spacing, i64* %ptr, align 4 + ret i64 *%ptr +} + +define i64 * @pre64idxneg256(i64** nocapture %out, i64 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre64idxneg256: +; CHECK: ldr x0, [x0] +; CHECK-NEXT: str x1, [x0, #-256]! +; CHECK-NEXT: ret + %tmp = load i64*, i64** %out, align 8 + %ptr = getelementptr inbounds i64, i64* %tmp, i64 -32 + store i64 %spacing, i64* %ptr, align 4 + ret i64 *%ptr +} + define i32 * @pre32(i32** nocapture %out, i32 %spacing) nounwind noinline ssp { ; CHECK-LABEL: pre32: ; CHECK: ldr x0, [x0] @@ -169,6 +284,29 @@ define i32 * @pre32(i32** nocapture %out, i32 %spacing) nounwind noinline ssp { ret i32 *%ptr } +define i32 * @pre32idxpos256(i32** nocapture %out, i32 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre32idxpos256: +; CHECK: ldr x{{[0-9+]}}, [x0] +; CHECK-NEXT: add x0, x{{[0-9+]}}, #256 +; CHECK-NEXT: str w1, [x{{[0-9+]}}, #256] +; CHECK-NEXT: ret + %tmp = load i32*, i32** %out, align 8 + %ptr = getelementptr inbounds i32, i32* %tmp, i64 64 + store i32 %spacing, i32* %ptr, align 4 + ret i32 *%ptr +} + +define i32 * @pre32idxneg256(i32** nocapture %out, i32 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre32idxneg256: +; CHECK: ldr x0, [x0] +; CHECK-NEXT: str w1, [x0, #-256]! +; CHECK-NEXT: ret + %tmp = load i32*, i32** %out, align 8 + %ptr = getelementptr inbounds i32, i32* %tmp, i64 -64 + store i32 %spacing, i32* %ptr, align 4 + ret i32 *%ptr +} + define i16 * @pre16(i16** nocapture %out, i16 %spacing) nounwind noinline ssp { ; CHECK-LABEL: pre16: ; CHECK: ldr x0, [x0] @@ -180,6 +318,29 @@ define i16 * @pre16(i16** nocapture %out, i16 %spacing) nounwind noinline ssp { ret i16 *%ptr } +define i16 * @pre16idxpos256(i16** nocapture %out, i16 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre16idxpos256: +; CHECK: ldr x{{[0-9+]}}, [x0] +; CHECK-NEXT: add x0, x{{[0-9+]}}, #256 +; CHECK-NEXT: strh w1, [x{{[0-9+]}}, #256] +; CHECK-NEXT: ret + %tmp = load i16*, i16** %out, align 8 + %ptr = getelementptr inbounds i16, i16* %tmp, i64 128 + store i16 %spacing, i16* %ptr, align 4 + ret i16 *%ptr +} + +define i16 * @pre16idxneg256(i16** nocapture %out, i16 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre16idxneg256: +; CHECK: ldr x0, [x0] +; CHECK-NEXT: strh w1, [x0, #-256]! +; CHECK-NEXT: ret + %tmp = load i16*, i16** %out, align 8 + %ptr = getelementptr inbounds i16, i16* %tmp, i64 -128 + store i16 %spacing, i16* %ptr, align 4 + ret i16 *%ptr +} + define i8 * @pre8(i8** nocapture %out, i8 %spacing) nounwind noinline ssp { ; CHECK-LABEL: pre8: ; CHECK: ldr x0, [x0] @@ -191,6 +352,29 @@ define i8 * @pre8(i8** nocapture %out, i8 %spacing) nounwind noinline ssp { ret i8 *%ptr } +define i8 * @pre8idxpos256(i8** nocapture %out, i8 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre8idxpos256: +; CHECK: ldr x{{[0-9+]}}, [x0] +; CHECK-NEXT: add x0, x{{[0-9+]}}, #256 +; CHECK-NEXT: strb w1, [x{{[0-9+]}}, #256] +; CHECK-NEXT: ret + %tmp = load i8*, i8** %out, align 8 + %ptr = getelementptr inbounds i8, i8* %tmp, i64 256 + store i8 %spacing, i8* %ptr, align 4 + ret i8 *%ptr +} + +define i8 * @pre8idxneg256(i8** nocapture %out, i8 %spacing) nounwind noinline ssp { +; CHECK-LABEL: pre8idxneg256: +; CHECK: ldr x0, [x0] +; CHECK-NEXT: strb w1, [x0, #-256]! +; CHECK-NEXT: ret + %tmp = load i8*, i8** %out, align 8 + %ptr = getelementptr inbounds i8, i8* %tmp, i64 -256 + store i8 %spacing, i8* %ptr, align 4 + ret i8 *%ptr +} + define i32 * @pretrunc64to32(i32** nocapture %out, i64 %spacing) nounwind noinline ssp { ; CHECK-LABEL: pretrunc64to32: ; CHECK: ldr x0, [x0] -- 2.7.4