From: Sjoerd Meijer Date: Thu, 31 Jan 2019 08:38:06 +0000 (+0000) Subject: [ARM] Thumb2: ConstantMaterializationCost X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e964d52e2d504fd2b58d2135ac4aa2af2d299c4d;p=llvm [ARM] Thumb2: ConstantMaterializationCost Constants can also be materialised using the negated value and a MVN, and this case seem to have been missed for Thumb2. To check the constant materialisation costs, we now call getT2SOImmVal twice, once for the original constant and then also for its negated value, and this function checks if the constant can both be splatted or rotated. This was revealed by a test that optimises for minsize: instead of a LDR literal pool load and having a literal pool entry, just a MVN with an immediate is smaller (and also faster). Differential Revision: https://reviews.llvm.org/D57327 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352737 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index a51cbda4f1d..17a82e4c800 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -452,8 +452,10 @@ unsigned ARMDAGToDAGISel::ConstantMaterializationCost(unsigned Val) const { if (Subtarget->isThumb()) { if (Val <= 255) return 1; // MOV if (Subtarget->hasV6T2Ops() && - (Val <= 0xffff || ARM_AM::getT2SOImmValSplatVal(Val) != -1)) - return 1; // MOVW + (Val <= 0xffff || // MOV + ARM_AM::getT2SOImmVal(Val) != -1 || // MOVW + ARM_AM::getT2SOImmVal(~Val) != -1)) // MVN + return 1; if (Val <= 510) return 2; // MOV + ADDi8 if (~Val <= 255) return 2; // MOV + MVN if (ARM_AM::isThumbImmShiftedVal(Val)) return 2; // MOV + LSL diff --git a/test/CodeGen/ARM/subtarget-no-movt.ll b/test/CodeGen/ARM/subtarget-no-movt.ll index fb0d5adc3f4..3fb84f00524 100644 --- a/test/CodeGen/ARM/subtarget-no-movt.ll +++ b/test/CodeGen/ARM/subtarget-no-movt.ll @@ -1,99 +1,97 @@ -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - | FileCheck -check-prefix=NO-OPTION %s -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=-no-movt | FileCheck -check-prefix=USE-MOVT %s -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=+no-movt | FileCheck -check-prefix=NO-USE-MOVT %s -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 | FileCheck -check-prefix=NO-OPTION-O0 %s -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=-no-movt | FileCheck -check-prefix=USE-MOVT-O0 %s -; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=+no-movt | FileCheck -check-prefix=NO-USE-MOVT-O0 %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefixes=CHECK,NO-OPTION,NO-OPTION-COMMON %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=-no-movt | \ +; RUN: FileCheck -check-prefixes=CHECK,USE-MOVT,USE-MOVT-COMMON %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=+no-movt | \ +; RUN: FileCheck -check-prefixes=CHECK,NO-USE-MOVT,NO-USE-MOVT-COMMON %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 | \ +; RUN: FileCheck -check-prefixes=CHECK,NO-OPTION-O0,NO-OPTION-COMMON %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=-no-movt | \ +; RUN: FileCheck -check-prefixes=CHECK,USE-MOVT-O0,USE-MOVT-COMMON %s +; RUN: llc -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=+no-movt | \ +; RUN: FileCheck -check-prefixes=CHECK,NO-USE-MOVT-O0,NO-USE-MOVT-COMMON %s target triple = "thumb-apple-darwin" -; NO-OPTION-LABEL: {{_?}}foo0 -; NO-OPTION: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-OPTION: [[L0]]: -; NO-OPTION: .long 2296237089 +; NO-OPTION-COMMON-LABEL: {{_?}}foo0 +; NO-OPTION-COMMON: ldr [[R0:r[0-9]+]], [[L0:.*]] +; NO-OPTION-COMMON: [[L0]]: +; NO-OPTION-COMMON: .long 2296237089 -; NO-OPTION-O0-LABEL: {{_?}}foo0 -; NO-OPTION-O0: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-OPTION-O0: [[L0]]: -; NO-OPTION-O0: .long 2296237089 +; USE-MOVT-COMMON-LABEL: {{_?}}foo0 +; USE-MOVT-COMMON: movw [[R0:r[0-9]+]], #52257 +; USE-MOVT-COMMON: movt [[R0]], #35037 -; USE-MOVT-LABEL: {{_?}}foo0 -; USE-MOVT: movw [[R0:r[0-9]+]], #52257 -; USE-MOVT: movt [[R0]], #35037 - -; USE-MOVT-O0-LABEL: {{_?}}foo0 -; USE-MOVT-O0: movw [[R0:r[0-9]+]], #52257 -; USE-MOVT-O0: movt [[R0]], #35037 - -; NO-USE-MOVT-LABEL: {{_?}}foo0 -; NO-USE-MOVT: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-USE-MOVT: [[L0]]: -; NO-USE-MOVT: .long 2296237089 - -; NO-USE-MOVT-O0-LABEL: {{_?}}foo0 -; NO-USE-MOVT-O0: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-USE-MOVT-O0: [[L0]]: -; NO-USE-MOVT-O0: .long 2296237089 +; NO-USE-MOVT-COMMON-LABEL: {{_?}}foo0 +; NO-USE-MOVT-COMMON: ldr [[R0:r[0-9]+]], [[L0:.*]] +; NO-USE-MOVT-COMMON: [[L0]]: +; NO-USE-MOVT-COMMON: .long 2296237089 define i32 @foo0(i32 %a) #0 { %1 = xor i32 -1998730207, %a ret i32 %1 } -; NO-OPTION-LABEL: {{_?}}foo1 -; NO-OPTION: movw [[R0:r[0-9]+]], #52257 -; NO-OPTION: movt [[R0]], #35037 - -; NO-OPTION-O0-LABEL: {{_?}}foo1 -; NO-OPTION-O0: movw [[R0:r[0-9]+]], #52257 -; NO-OPTION-O0: movt [[R0]], #35037 +; NO-OPTION-COMMON-LABEL: {{_?}}foo1 +; NO-OPTION-COMMON: movw [[R0:r[0-9]+]], #52257 +; NO-OPTION-COMMON: movt [[R0]], #35037 -; USE-MOVT-LABEL: {{_?}}foo1 -; USE-MOVT: movw [[R0:r[0-9]+]], #52257 -; USE-MOVT: movt [[R0]], #35037 +; USE-MOVT-COMMON-LABEL: {{_?}}foo1 +; USE-MOVT-COMMON: movw [[R0:r[0-9]+]], #52257 +; USE-MOVT-COMMON: movt [[R0]], #35037 -; USE-MOVT-O0-LABEL: {{_?}}foo1 -; USE-MOVT-O0: movw [[R0:r[0-9]+]], #52257 -; USE-MOVT-O0: movt [[R0]], #35037 - -; NO-USE-MOVT-LABEL: {{_?}}foo1 -; NO-USE-MOVT: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-USE-MOVT: [[L0]]: -; NO-USE-MOVT: .long 2296237089 - -; NO-USE-MOVT-O0-LABEL: {{_?}}foo1 -; NO-USE-MOVT-O0: ldr [[R0:r[0-9]+]], [[L0:.*]] -; NO-USE-MOVT-O0: [[L0]]: -; NO-USE-MOVT-O0: .long 2296237089 +; NO-USE-MOVT-COMMON-LABEL: {{_?}}foo1 +; NO-USE-MOVT-COMMON: ldr [[R0:r[0-9]+]], [[L0:.*]] +; NO-USE-MOVT-COMMON: [[L0]]: +; NO-USE-MOVT-COMMON: .long 2296237089 define i32 @foo1(i32 %a) { %1 = xor i32 -1998730207, %a ret i32 %1 } -; NO-OPTION-LABEL: {{_?}}foo2 +; NO-OPTION-COMMON-LABEL: {{_?}}foo2 ; NO-OPTION: mov.w [[R0:r[0-9]+]], #-536813568 - -; USE-MOVT-LABEL: {{_?}}foo2 -; USE-MOVT: mov.w [[R0:r[0-9]+]], #-536813568 - -; NO-USE-MOVT-LABEL: {{_?}}foo2 -; NO-USE-MOVT: mov.w [[R0:r[0-9]+]], #-536813568 - -; NO-OPTION-O0-LABEL: {{_?}}foo2 ; NO-OPTION-O0: movw [[R0:r[0-9]+]], #57344 ; NO-OPTION-O0: movt [[R0]], #57344 -; USE-MOVT-O0-LABEL: {{_?}}foo2 -; USE-MOVT-O0: movw [[R0:r[0-9]+]], #57344 -; USE-MOVTT-O0: movt [[R0]], #57344 +; USE-MOVT-COMMON-LABEL: {{_?}}foo2 +; USE-MOVT: mov.w [[R0:r[0-9]+]], #-536813568 +; USE-MOVT-O0: movw [[R0:r[0-9]+]], #57344 +; USE-MOVT-O0: movt [[R0]], #57344 -; NO-USE-MOVT-O0-LABEL: {{_?}}foo2 +; NO-USE-MOVT-COMMON-LABEL: {{_?}}foo2 +; NO-USE-MOVT: mov.w [[R0:r[0-9]+]], #-536813568 ; NO-USE-MOVT-O0: ldr [[R0:r[0-9]+]], [[L0:.*]] ; NO-USE-MOVT-O0: [[L0]]: ; NO-USE-MOVT-O0: .long 3758153728 @ 0xe000e000 + define i32 @foo2() { %1 = load i32, i32* inttoptr (i32 -536813568 to i32*) ; load from 0xe000e000 ret i32 %1 } attributes #0 = { "target-features"="+no-movt" } + +define hidden i32 @no_litpool() minsize optsize { +; CHECK-LABEL: no_litpool: +; CHECK: mov.w r{{.}}, #65536 +; CHECK: mov.w r{{.}}, #-134217728 +; CHECK: mvn r{{.}}, #-134217728 +entry: + %call0 = tail call i32 @eat_const(i32 65536) + %call1 = tail call i32 @eat_const(i32 -134217728) + %call2 = tail call i32 @eat_const(i32 134217727) + ret i32 %call2 +} + +define hidden i32 @litpool() minsize optsize { +; CHECK-LABEL: litpool: +; CHECK: ldr r0, {{.*}}LCPI{{.*}} +; CHECK-NEXT: b.w {{.*}}eat_const +entry: + %call1 = tail call i32 @eat_const(i32 8388601) + ret i32 %call1 +} + +declare dso_local i32 @eat_const(i32) +