Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -10243,8 +10243,10 @@ // 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 *= -1; + if (!isInt<9>(RHSC)) return false; IsInc = (Op->getOpcode() == ISD::ADD); Offset = Op->getOperand(1); Index: test/CodeGen/AArch64/arm64-indexed-memory.ll =================================================================== --- test/CodeGen/AArch64/arm64-indexed-memory.ll +++ test/CodeGen/AArch64/arm64-indexed-memory.ll @@ -11,6 +11,17 @@ 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 +33,17 @@ 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 +55,17 @@ 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 +77,17 @@ 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 +202,17 @@ 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 +224,17 @@ 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 +246,17 @@ 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 +268,17 @@ 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]