diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp --- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp +++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp @@ -337,6 +337,11 @@ Idx == 1) return 0; + // Leave any gep offsets for the CodeGenPrepare, which will do a better job at + // splitting any large offsets. + if (Opcode == Instruction::GetElementPtr && Idx != 0) + return 0; + if (Opcode == Instruction::And) { // UXTB/UXTH if (Imm == 255 || Imm == 65535) diff --git a/llvm/test/CodeGen/ARM/gep-imm.ll b/llvm/test/CodeGen/ARM/gep-imm.ll --- a/llvm/test/CodeGen/ARM/gep-imm.ll +++ b/llvm/test/CodeGen/ARM/gep-imm.ll @@ -37,16 +37,15 @@ define void @large(i32 %a, i32 %b, i32 *%c, i32* %d) { ; CHECKV6M-LABEL: large: ; CHECKV6M: @ %bb.0: @ %entry -; CHECKV6M-NEXT: .save {r4, r5, r7, lr} -; CHECKV6M-NEXT: push {r4, r5, r7, lr} -; CHECKV6M-NEXT: movs r4, #125 -; CHECKV6M-NEXT: lsls r4, r4, #4 -; CHECKV6M-NEXT: lsls r4, r4, #2 -; CHECKV6M-NEXT: str r0, [r3, r4] -; CHECKV6M-NEXT: ldr r5, .LCPI1_0 -; CHECKV6M-NEXT: str r1, [r3, r5] -; CHECKV6M-NEXT: str r0, [r2, r4] -; CHECKV6M-NEXT: pop {r4, r5, r7, pc} +; CHECKV6M-NEXT: .save {r4, lr} +; CHECKV6M-NEXT: push {r4, lr} +; CHECKV6M-NEXT: ldr r4, .LCPI1_0 +; CHECKV6M-NEXT: str r1, [r3, r4] +; CHECKV6M-NEXT: movs r1, #125 +; CHECKV6M-NEXT: lsls r1, r1, #6 +; CHECKV6M-NEXT: str r0, [r3, r1] +; CHECKV6M-NEXT: str r0, [r2, r1] +; CHECKV6M-NEXT: pop {r4, pc} ; CHECKV6M-NEXT: .p2align 2 ; CHECKV6M-NEXT: @ %bb.1: ; CHECKV6M-NEXT: .LCPI1_0: @@ -82,47 +81,42 @@ define void @huge(i32 %a, i32 %b, i32 *%c, i32* %d) { ; CHECKV6M-LABEL: huge: ; CHECKV6M: @ %bb.0: @ %entry -; CHECKV6M-NEXT: .save {r4, r5, r7, lr} -; CHECKV6M-NEXT: push {r4, r5, r7, lr} +; CHECKV6M-NEXT: .save {r4, lr} +; CHECKV6M-NEXT: push {r4, lr} ; CHECKV6M-NEXT: ldr r4, .LCPI2_0 -; CHECKV6M-NEXT: lsls r4, r4, #2 -; CHECKV6M-NEXT: str r0, [r3, r4] -; CHECKV6M-NEXT: ldr r5, .LCPI2_1 -; CHECKV6M-NEXT: str r1, [r3, r5] -; CHECKV6M-NEXT: str r0, [r2, r4] -; CHECKV6M-NEXT: pop {r4, r5, r7, pc} +; CHECKV6M-NEXT: str r1, [r3, r4] +; CHECKV6M-NEXT: ldr r1, .LCPI2_1 +; CHECKV6M-NEXT: str r0, [r3, r1] +; CHECKV6M-NEXT: str r0, [r2, r1] +; CHECKV6M-NEXT: pop {r4, pc} ; CHECKV6M-NEXT: .p2align 2 ; CHECKV6M-NEXT: @ %bb.1: ; CHECKV6M-NEXT: .LCPI2_0: -; CHECKV6M-NEXT: .long 200000 @ 0x30d40 -; CHECKV6M-NEXT: .LCPI2_1: ; CHECKV6M-NEXT: .long 1200000 @ 0x124f80 +; CHECKV6M-NEXT: .LCPI2_1: +; CHECKV6M-NEXT: .long 800000 @ 0xc3500 ; ; CHECKV7M-LABEL: huge: ; CHECKV7M: @ %bb.0: @ %entry -; CHECKV7M-NEXT: .save {r7, lr} -; CHECKV7M-NEXT: push {r7, lr} -; CHECKV7M-NEXT: movw r12, #3392 -; CHECKV7M-NEXT: movw lr, #20352 -; CHECKV7M-NEXT: movt r12, #3 -; CHECKV7M-NEXT: movt lr, #18 -; CHECKV7M-NEXT: str.w r0, [r3, r12, lsl #2] -; CHECKV7M-NEXT: str.w r1, [r3, lr] -; CHECKV7M-NEXT: str.w r0, [r2, r12, lsl #2] -; CHECKV7M-NEXT: pop {r7, pc} +; CHECKV7M-NEXT: movw r12, #20352 +; CHECKV7M-NEXT: movt r12, #18 +; CHECKV7M-NEXT: str.w r1, [r3, r12] +; CHECKV7M-NEXT: movw r1, #13568 +; CHECKV7M-NEXT: movt r1, #12 +; CHECKV7M-NEXT: str r0, [r3, r1] +; CHECKV7M-NEXT: str r0, [r2, r1] +; CHECKV7M-NEXT: bx lr ; ; CHECKV7A-LABEL: huge: ; CHECKV7A: @ %bb.0: @ %entry -; CHECKV7A-NEXT: .save {r7, lr} -; CHECKV7A-NEXT: push {r7, lr} -; CHECKV7A-NEXT: movw r12, #3392 -; CHECKV7A-NEXT: movw lr, #20352 -; CHECKV7A-NEXT: movt r12, #3 -; CHECKV7A-NEXT: movt lr, #18 -; CHECKV7A-NEXT: str.w r0, [r3, r12, lsl #2] -; CHECKV7A-NEXT: str.w r1, [r3, lr] -; CHECKV7A-NEXT: str.w r0, [r2, r12, lsl #2] -; CHECKV7A-NEXT: pop {r7, pc} +; CHECKV7A-NEXT: movw r12, #20352 +; CHECKV7A-NEXT: movt r12, #18 +; CHECKV7A-NEXT: str.w r1, [r3, r12] +; CHECKV7A-NEXT: movw r1, #13568 +; CHECKV7A-NEXT: movt r1, #12 +; CHECKV7A-NEXT: str r0, [r3, r1] +; CHECKV7A-NEXT: str r0, [r2, r1] +; CHECKV7A-NEXT: bx lr entry: %arrayidx = getelementptr inbounds i32, i32* %d, i32 200000 store i32 %a, i32* %arrayidx, align 4 diff --git a/llvm/test/Transforms/ConstantHoisting/ARM/gep-struct-index.ll b/llvm/test/Transforms/ConstantHoisting/ARM/gep-struct-index.ll --- a/llvm/test/Transforms/ConstantHoisting/ARM/gep-struct-index.ll +++ b/llvm/test/Transforms/ConstantHoisting/ARM/gep-struct-index.ll @@ -19,14 +19,11 @@ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } -; Indices for GEPs that index into a struct type should not be hoisted. +; Indices for GEPs should not be hoisted. define i32 @test1(%T* %P) nounwind { ; CHECK-LABEL: @test1 -; CHECK: %const = bitcast i32 256 to i32 -; CHECK: %addr1 = getelementptr %T, %T* %P, i32 %const, i32 256 -; CHECK: %addr2 = getelementptr %T, %T* %P, i32 %const, i32 256 -; The first index into the pointer is hoisted, but the second one into the -; struct isn't. +; CHECK: %addr1 = getelementptr %T, %T* %P, i32 256, i32 256 +; CHECK: %addr2 = getelementptr %T, %T* %P, i32 256, i32 256 %addr1 = getelementptr %T, %T* %P, i32 256, i32 256 %tmp1 = load i32, i32* %addr1 %addr2 = getelementptr %T, %T* %P, i32 256, i32 256