Commit Graph

3618 Commits

Author SHA1 Message Date
Peter Smith 944e6c56f7 [ARM] Account for implicit IT when calculating inline asm size
When deciding if it is safe to optimize a conditional branch to a CBZ or
CBNZ the offsets of the BasicBlocks from the start of the function are
estimated. For inline assembly the generic getInlineAsmLength() function is
used to get a worst case estimate of the inline assembly by multiplying the
number of instructions by the max instruction size of 4 bytes. This
unfortunately doesn't take into account the generation of Thumb implicit IT
instructions. In edge cases such as when all the instructions in the block
are 4-bytes in size and there is an implicit IT then the size is
underestimated. This can cause an out of range CBZ or CBNZ to be generated.

The patch takes a conservative approach and assumes that every instruction
in the inline assembly block may have an implicit IT.

Fixes pr31805

Differential Revision: https://reviews.llvm.org/D52834



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343960 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-08 09:38:28 +00:00
Eli Friedman b10248393f [ARM] Fix correctness checks in promoteToConstantPool.
Correctly check for relocations in the constant to promote. And don't
allow promoting a constant multiple times.

This partially fixes https://bugs.llvm.org//show_bug.cgi?id=32780 ;
it's not a complete fix because we also need to prevent
ARMConstantIslands from cloning the constant.

(-arm-promote-constant is currently off by default, and it stays off
with this patch. I'll look into turning it on again when all the known
issues are fixed.)

Differential Revision: https://reviews.llvm.org/D51472



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343361 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-28 20:27:31 +00:00
Eli Friedman 770516eb32 [ARM] Use preferred alignment for constants in promoteToConstantPool.
This mostly affects IR generated by non-clang frontends because clang
generally sets the alignment of globals explicitly.

Fixes https://bugs.llvm.org//show_bug.cgi?id=32394 .

(-arm-promote-constant is currently off by default, and it stays off
with this patch. I'll look into turning it on again when all the known
issues are fixed.)

Differential Revision: https://reviews.llvm.org/D51469



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343359 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-28 20:21:51 +00:00
David Spickett c2c1024556 [ARM] Allow execute only code on Cortex-m23
The NoMovt feature prevents the use of MOVW/MOVT
instructions on Cortex-M23 for performance reasons.
These instructions are required for execute only code
so NoMovt should be disabled when that option is enabled.

Differential Revision: https://reviews.llvm.org/D52551



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343302 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-28 08:55:19 +00:00
Francis Visoiu Mistrih fa73cae344 [CodeGen] Always print register ties in MI::dump()
It was the case when calling MO::dump(), but MI::dump() was still
depending on hasComplexRegisterTies().

The MIR output is not affected.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343107 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-26 13:33:09 +00:00
Sam Parker 78e19a9d43 [ARM] Fix for PR39060
When calculating whether a value can safely overflow for use by an
icmp, we weren't checking that the value couldn't wrap around. To do
this we need the icmp to be using a constant, as well as the incoming
add or sub.

bugzilla report: https://bugs.llvm.org/show_bug.cgi?id=39060

Differential Revision: https://reviews.llvm.org/D52463


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343092 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-26 10:56:00 +00:00
David Green ae073c99a4 [CodeGen] Enable tail calls for functions with NonNull attributes.
Adding NonNull as attributes to returned pointers has the unfortunate side
effect of disabling tail calls. This patch ignores the NonNull attribute when
we decide whether to tail merge, in the same way that we ignore the NoAlias
attribute, as it has no affect on the call sequence.

Differential Revision: https://reviews.llvm.org/D52238


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343091 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-26 10:46:18 +00:00
Hans Wennborg 12076fcf79 Revert r342870 "[ARM] bottom-top mul support ARMParallelDSP"
This broke Chromium's Android build (https://crbug.com/889390) and the
polly-aosp buildbot
(http://lab.llvm.org:8011/builders/aosp-O3-polly-before-vectorizer-unprofitable).

> Originally committed in rL342210 but was reverted in rL342260 because
> it was causing issues in vectorized code, because I had forgotten to
> ensure that we're operating on scalar values.
>
> Original commit message:
>
> On failing to find sequences that can be converted into dual macs,
> try to find sequential 16-bit loads that are used by muls which we
> can then use smultb, smulbt, smultt with a wide load.
>
> Differential Revision: https://reviews.llvm.org/D51983

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343082 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-26 08:41:50 +00:00
Sjoerd Meijer 857469dbb1 [ARM] Do not fuse VADD and VMUL on the Cortex-M4 and Cortex-M33
A sequence of VMUL and VADD instructions always give the same or better
performance than a fused VMLA instruction on the Cortex-M4 and Cortex-M33.
Executing the VMUL and VADD back-to-back requires the same cycles, but
having separate instructions allows scheduling to avoid the hazard between
these 2 instructions.

Differential Revision: https://reviews.llvm.org/D52289


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342874 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-24 12:02:50 +00:00
Luke Cheeseman 33b1a96b81 [ARM][ARMLoadStoreOptimizer]
- The load store optimizer is currently merging multiple loads/stores into VLDM/VSTM with more than 16 doubleword registers
- This is an UNPREDICTABLE instruction and shouldn't be done
- It looks like the Limit for how many registers included in a merge got dropped at some point so I am reintroducing it in this patch
- This fixes https://bugs.llvm.org/show_bug.cgi?id=38389

Differential Revision: https://reviews.llvm.org/D52085



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342872 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-24 10:42:22 +00:00
Sam Parker 972331c62b [ARM] bottom-top mul support ARMParallelDSP
Originally committed in rL342210 but was reverted in rL342260 because
it was causing issues in vectorized code, because I had forgotten to
ensure that we're operating on scalar values.

Original commit message:

On failing to find sequences that can be converted into dual macs,
try to find sequential 16-bit loads that are used by muls which we
can then use smultb, smulbt, smultt with a wide load.

Differential Revision: https://reviews.llvm.org/D51983


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342870 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-24 09:34:06 +00:00
Oliver Stannard bb4c357000 [ARM] Fix unwind information for floating point registers
Fixes the unwind information generated for floating-point registers.
Previously, all padding registers were assumed to be four bytes wide. Now, the
width of the register is used to specify the amount of padding.

Patch by Jackson Woodruff!

Differential revision: https://reviews.llvm.org/D51494



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342545 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-19 13:25:31 +00:00
John Brawn 0f5ab3b66f [TargetLowering] Android has sincos functions
Since Android API version 9 the Android libm has had the sincos functions, so
they should be recognised as libcalls and sincos optimisation should be applied.

Differential Revision: https://reviews.llvm.org/D52025


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342471 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-18 13:18:21 +00:00
Volodymyr Sapsai e85b236f17 Revert "[ARM] Cleanup ARM CGP isSupportedValue"
This reverts r342395 as it caused error

> Argument value type does not match pointer operand type!
>   %0 = atomicrmw volatile xchg i8* %_Value1, i32 1 monotonic, !dbg !25
>  i8in function atomic_flag_test_and_set
> fatal error: error in backend: Broken function found, compilation aborted!

on bot http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/

More details are available at https://reviews.llvm.org/D52080


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342431 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-18 00:11:55 +00:00
Sam Parker a72fb54240 [ARM] Cleanup ARM CGP isSupportedValue
isSupportedValue explicitly checked and accepted many types of value,
primarily for debugging reasons. Remove most of these checks and do a
bit of refactoring now that the pass is more stable. This also enables
ZExts to be sources, but this has very little practical benefit at the
moment extend instructions will still be introduced.

Differential Revision: https://reviews.llvm.org/D52080


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342395 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-17 13:57:39 +00:00
Sam Parker d377332d77 [ARM] Disallow icmp with negative imm and overflow
We allow overflowing instructions if they're decreasing and only used
by an unsigned compare. Add the extra condition that the icmp cannot
be using a negative immediate.

Differential Revision: https://reviews.llvm.org/D52102


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342392 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-17 13:48:25 +00:00
Reid Kleckner 70de09a348 Revert r342210 "[ARM] bottom-top mul support in ARMParallelDSP"
It causes assertion failures while building Skia for Android in
Chromium:
https://ci.chromium.org/buildbot/chromium.clang/ToTAndroid/4550

Reduction forthcoming.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342260 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-14 18:44:37 +00:00
Sam Parker ad72545325 [ARM] bottom-top mul support in ARMParallelDSP
On failing to find sequences that can be converted into dual macs,
try to find sequential 16-bit loads that are used by muls which we
can then use smultb, smulbt, smultt with a wide load.

Differential Revision: https://reviews.llvm.org/D51983


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342210 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-14 08:09:09 +00:00
Sam Parker 94436041e4 [ARM] Allow truncs as sources in ARM CGP
We previously only allowed truncs as sinks, but now allow them as
sources too. We do this by checking that the result type is the
narrow type that we're trying to optimise for.

Differential Revision: https://reviews.llvm.org/D51978


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342141 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-13 15:14:12 +00:00
Sam Parker a8d062c818 [ARM] Fix FixConst for ARMCodeGenPrepare
Part of FixConsts wrongly assumes either a 8- or 16-bit constant
which can result in the wrong constants being generated during
promotion.

Differential Revision: https://reviews.llvm.org/D52032


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342140 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-13 14:48:10 +00:00
Tim Northover 29369e8ff6 ARM: align loops to 4 bytes on Cortex-M3 and Cortex-M4.
The Technical Reference Manuals for these two CPUs state that branching
to an unaligned 32-bit instruction incurs an extra pipeline reload
penalty. That's bad.

This also enables the optimization at -Os since it costs on average one
byte per loop in return for 1 cycle per iteration, which is pretty good
going.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342127 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-13 10:28:05 +00:00
Diogo N. Sampaio cfe06dbe7c [ARM] Tighten f64<->f16 conversion requirements
Fix missing Requires fields.

Patch by Bernard Ogden (bogden)

Reviewers: SjoerdMeijer, javed.absar, t.p.northover	

Reviewed By: t.p.northover

Differential Revision: https://reviews.llvm.org/D51631


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342061 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-12 16:24:43 +00:00
Sam Parker ddd717485f [ARM] Exchange MAC operands in ARMParallelDSP
SMLAD and SMLALD instructions also come in the form of SMLADX and
SMLALDX which perform an exchange on their second operand. To support
this, more of the loads in the MAC candidates are compared for
sequential access and a boolean value has been added to BinOpChain.

AddMACCandiate has been refactored into a small pattern matching
state machine to reduce the amount of duplicated code, but also to
enable the matching to be more flexible. CreateParallelMACPairs now
iterates through all the candidates to find parallel ones.

Differential Revision: https://reviews.llvm.org/D51424


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342033 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-12 09:17:44 +00:00
Sam Parker f8479a89f4 [ARM] Allow bitcasts in ARMCodeGenPrepare
Allow bitcasts in the use-def chains, treating them as sources.

Differential Revision: https://reviews.llvm.org/D50758


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342032 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-12 09:11:48 +00:00
Sam Parker 880c654ad4 [ARM] Add smlald support in ARMParallelDSP
Search from i64 reducing phis, as well as i32, to allow the
generation of smlald instructions.

Differential Revision: https://reviews.llvm.org/D51101


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341941 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-11 14:01:22 +00:00
Tim Northover 361c297c9d ARM: fix Thumb2 CodeGen for ldrex with folded frame-index.
Because t2LDREX (& t2STREX) were marked as AddrModeNone, but did allow a
FrameIndex operand, rewriteT2FrameIndex asserted. This gives them a
proper addressing-mode and tells the rewriter about it so that encodable
offsets are exploited and others are rejected.

Should fix PR38828.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341642 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-07 09:21:25 +00:00
Eric Christopher 42eb082d63 The initial .text section generated in object files was missing the
SHF_ARM_PURECODE flag when being built with the -mexecute-only flag.
All code sections of an ELF must have the flag set for the final .text
section to be execute-only, otherwise the flag gets removed.

A HasData flag is added to MCSection to aid in the determination that
the section is empty. A virtual setTargetSectionFlags is added to
MCELFObjectTargetWriter to allow subclasses to set target specific
section flags to be added to sections which we then use in the ARM
backend to set SHF_ARM_PURECODE.

Patch by Ivan Lozano!

Reviewed By: echristo

Differential Revision: https://reviews.llvm.org/D48792

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341593 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-06 22:09:31 +00:00
Sanjay Patel 39f79ecf00 [DAGCombiner] try to convert pow(x, 0.25) to sqrt(sqrt(x))
This was proposed as an IR transform in D49306, but it was not clearly justifiable as a canonicalization. 
Here, we only do the transform when the target tells us that sqrt can be lowered with inline code.

This is the basic case. Some potential enhancements are in the TODO comments:

1. Generalize the transform for other exponents (allow more than 2 sqrt calcs if that's really cheaper).
2. If we have less fast-math-flags, generate code to avoid -0.0 and/or INF.
3. Allow the transform when optimizing/minimizing size (might require a target hook to get that right).

Note that by default, x86 converts single-precision sqrt calcs into sqrt reciprocal estimate with 
refinement. That codegen is controlled by CPU attributes and can be manually overridden. We have plenty 
of test coverage for that already, so I didn't bother to include extra testing for that here. AArch uses 
its full-precision ops in all cases (not sure if that's the intended behavior or not, but that should 
also be covered by existing tests).

Differential Revision: https://reviews.llvm.org/D51630 


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341481 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-05 17:01:56 +00:00
Martin Storsjo d67818ff54 [MinGW] [ARM] Add stubs for potential automatic dllimported variables
The runtime pseudo relocations can't handle the ARM format embedded
addresses in movw/movt pairs. By using stubs, the potentially
dllimported addresses can be touched up by the runtime pseudo relocation
framework.

Differential Revision: https://reviews.llvm.org/D51450

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341176 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-31 08:00:25 +00:00
Ties Stuij 6089d1a3c7 [CodeGen] emit inline asm clobber list warnings for reserved (cont)
Summary:
This is a continuation of https://reviews.llvm.org/D49727
Below the original text, current changes in the comments:

Currently, in line with GCC, when specifying reserved registers like sp or pc on an inline asm() clobber list, we don't always preserve the original value across the statement. And in general, overwriting reserved registers can have surprising results.

For example:

  extern int bar(int[]);
  
  int foo(int i) {
    int a[i]; // VLA
    asm volatile(
        "mov r7, #1"
      :
      :
      : "r7"
    );
  
    return 1 + bar(a);
  }

Compiled for thumb, this gives:

  $ clang --target=arm-arm-none-eabi -march=armv7a -c test.c -o - -S -O1 -mthumb
  ...
  foo:
          .fnstart
  @ %bb.0:                                @ %entry
          .save   {r4, r5, r6, r7, lr}
          push    {r4, r5, r6, r7, lr}
          .setfp  r7, sp, #12
          add     r7, sp, #12
          .pad    #4
          sub     sp, #4
          movs    r1, #7
          add.w   r0, r1, r0, lsl #2
          bic     r0, r0, #7
          sub.w   r0, sp, r0
          mov     sp, r0
          @APP
          mov.w   r7, #1
          @NO_APP
          bl      bar
          adds    r0, #1
          sub.w   r4, r7, #12
          mov     sp, r4
          pop     {r4, r5, r6, r7, pc}
  ...

r7 is used as the frame pointer for thumb targets, and this function needs to restore the SP from the FP because of the variable-length stack allocation a. r7 is clobbered by the inline assembly (and r7 is included in the clobber list), but LLVM does not preserve the value of the frame pointer across the assembly block.

This type of behavior is similar to GCC's and has been discussed on the bugtracker: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11807 . No consensus seemed to have been reached on the way forward. Clang behavior has briefly been discussed on the CFE mailing (starting here: http://lists.llvm.org/pipermail/cfe-dev/2018-July/058392.html). I've opted for following Eli Friedman's advice to print warnings when there are reserved registers on the clobber list so as not to diverge from GCC behavior for now.

The patch uses MachineRegisterInfo's target-specific knowledge of reserved registers, just before we convert the inline asm string in the AsmPrinter.

If we find a reserved register, we print a warning:

  repro.c:6:7: warning: inline asm clobber list contains reserved registers: R7 [-Winline-asm]
        "mov r7, #1"
        ^

Reviewers: efriedma, olista01, javed.absar

Reviewed By: efriedma

Subscribers: eraman, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D51165

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341062 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-30 12:52:35 +00:00
Florian Hahn 3e54ac3b7f Fix "Q" and "R" inline assembly template modifiers for big-endian Arm
Consider the endianness of the target when printing register names.  This is in line with the documentation at http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers

Patch by Jackson Woodruff <jackson.woodruff@arm.com>

Reviewers: t.p.northover, echristo, javed.absar, efriedma

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D49778


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341052 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-30 10:28:23 +00:00
Huihui Zhang 6f7036edd3 [GlobalMerge] Fix GlobalMerge on bss external global variables.
Summary:
Global variables that are external and zero initialized are
supposed to be merged with global variables in the bss section
rather than the data section.

Reviewers: efriedma, rengolin, t.p.northover, javed.absar, asl, john.brawn, pcc

Reviewed By: efriedma

Subscribers: dmgreen, llvm-commits

Differential Revision: https://reviews.llvm.org/D51379

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341008 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-30 00:49:50 +00:00
Eli Friedman 575895c12e [ARM] Lower llvm.ctlz.i32 to a libcall when clz is not available.
The inline sequence is very long (about 70 bytes on Thumb1), so it's
not really a good idea to inline it, especially when optimizing for
size.

Differential Revision: https://reviews.llvm.org/D47917



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340458 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-22 21:47:14 +00:00
Martin Storsjo cab386f908 [ARM] Avoid injecting constant islands in movw+movt pairs on Windows
On Windows, movw+movt pairs with relocations are handled with a single
relocation that covers them both. Therefore we can't inject anything
between these instructions, otherwise the relocation (which in LLVM
only is treated as the movw instruction's relocation, while the movt
instruction's relocation is dropped) will end up bogus.

These instructions are bundled up until right before the constant
islands pass, making this effectively the only place that can split
them apart.

Differential Revision: https://reviews.llvm.org/D51032

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340451 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-22 20:34:12 +00:00
Eli Friedman 3c6df19a68 [ARM] Handle all-ones mask explicitly in targetShrinkDemandedConstant.
This avoids a potential infinite loop setting and unsetting bits in the
mask.

Reduced from a failure on the polly-aosp bot.

Differential Revision: https://reviews.llvm.org/D51066



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340446 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-22 20:13:45 +00:00
Sam Parker 284f256306 [ARM] Rotated operand patterns for *xtb16
Add intrinsic isel patterns for sxtb16, sxtab16, uxtb16 and uxtab16
so that they can perform a ror.

Differential Revision: https://reviews.llvm.org/D51034


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340405 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-22 12:58:36 +00:00
Sam Parker 48cb502069 [DAGCombiner] Reduce load widths of shifted masks
During combining, ReduceLoadWdith is used to combine AND nodes that
mask loads into narrow loads. This patch allows the mask to be a
shifted constant. This results in a narrow load which is then left
shifted to compensate for the new offset.

Differential Revision: https://reviews.llvm.org/D50432


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340261 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-21 10:26:59 +00:00
Eli Friedman cb762f1f3d [SelectionDAG] Improve the legalisation lowering of UMULO.
There is no way in the universe, that doing a full-width division in
software will be faster than doing overflowing multiplication in
software in the first place, especially given that this same full-width
multiplication needs to be done anyway.

This patch replaces the previous implementation with a direct lowering
into an overflowing multiplication algorithm based on half-width
operations.

Correctness of the algorithm was verified by exhaustively checking the
output of this algorithm for overflowing multiplication of 16 bit
integers against an obviously correct widening multiplication. Baring
any oversights introduced by porting the algorithm to DAG, confidence in
correctness of this algorithm is extremely high.

Following table shows the change in both t = runtime and s = space. The
change is expressed as a multiplier of original, so anything under 1 is
“better” and anything above 1 is worse.

+-------+-----------+-----------+-------------+-------------+
| Arch  | u64*u64 t | u64*u64 s | u128*u128 t | u128*u128 s |
+-------+-----------+-----------+-------------+-------------+
|   X64 |     -     |     -     |    ~0.5     |    ~0.64    |
|  i686 |   ~0.5    |   ~0.6666 |    ~0.05    |    ~0.9     |
| armv7 |     -     |   ~0.75   |      -      |    ~1.4     |
+-------+-----------+-----------+-------------+-------------+

Performance numbers have been collected by running overflowing
multiplication in a loop under `perf` on two x86_64 (one Intel Haswell,
other AMD Ryzen) based machines. Size numbers have been collected by
looking at the size of function containing an overflowing multiply in
a loop.

All in all, it can be seen that both performance and size has improved
except in the case of armv7 where code size has regressed for 128-bit
multiply. u128*u128 overflowing multiply on 32-bit platforms seem to
benefit from this change a lot, taking only 5% of the time compared to
original algorithm to calculate the same thing.

The final benefit of this change is that LLVM is now capable of lowering
the overflowing unsigned multiply for integers of any bit-width as long
as the target is capable of lowering regular multiplication for the same
bit-width. Previously, 128-bit overflowing multiply was the widest
possible.

Patch by Simonas Kazlauskas!

Differential Revision: https://reviews.llvm.org/D50310



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339922 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-16 18:39:39 +00:00
Sam Parker 3591e4cd93 [ARM] Ignore GEPs in ARMCodeGenPrepare
While searching through the use-def tree, ignore GetElementPtrInst
instructions because they don't need promoting and neither do their
indices. Otherwise, the wide indices prevent the transformation from
happening.

Differential Revision: https://reviews.llvm.org/D50762


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339871 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-16 12:24:40 +00:00
Sam Parker fd2bee90f5 [ARM] Allow zext in ARMCodeGenPrepare
Treat zext instructions as roots, like we do for truncs.

Differential Revision: https://reviews.llvm.org/D50759


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339868 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-16 11:54:09 +00:00
Sam Parker 7d16ffe5b7 [ARM] Allow signed icmps in ARMCodeGenPrepare
Originally committed in r339755 which was reverted in r339806 due to
an asan issue. The issue was caused by my assumption that operands to
a CallInst mapped to the FunctionType Params. CallInsts are now
handled by iterating over their ArgOperands instead of Operands.
    
Original Message:
  Treat signed icmps as 'sinks', allowing them to be in the use-def
  tree, enabling more promotions to be performed. As a sink, any
  promoted incoming values need to be truncated before being used by
  the signed icmp.
    
  Differential Revision: https://reviews.llvm.org/D50067


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339858 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-16 10:05:39 +00:00
Vitaly Buka 30db32fcf1 Revert "[ARM] Allow signed icmps in ARMCodeGenPrepare"
use-after-poison in check-llvm under asan

This reverts commit r339755.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339806 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-15 20:09:35 +00:00
Sam Parker 3dd5242055 [ARM] TypeSize lower bound for ARMCodeGenPrepare
We only try to promote types with are smaller than 16-bits, but we
also need to check that the type is not less than 8-bits.

Differential Revision: https://reviews.llvm.org/D50769


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339770 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-15 13:29:50 +00:00
Sam Parker 81654d2362 [ARM] Allow signed icmps in ARMCodeGenPrepare
Treat signed icmps as 'sinks', allowing them to be in the use-def
tree, enabling more promotions to be performed. As a sink, any
promoted incoming values need to be truncated before being used by
the signed icmp.

Differential Revision: https://reviews.llvm.org/D50067


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339755 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-15 08:23:03 +00:00
Sam Parker 90048a8206 [ARM] Allow pointer values in ARMCodeGenPrepare
Add pointers to the list of allowed types, but don't try to promote
them. Also fixed a bug with the promotion of undef values, so a new
value is now created instead of mutating in place. We also now only
promote if there's an instruction in the use-def chains other than
the icmp, sinks and sources.

Differential Revision: https://reviews.llvm.org/D50054


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339754 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-15 07:52:35 +00:00
Luke Geeson 4514ca2f1d [ARM] Added FP16 VREV Vector Instrinsic CodeGen support
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339546 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 08:37:41 +00:00
Eli Friedman 0365cb9494 [ARM] Adjust AND immediates to make them cheaper to select.
LLVM normally prefers to minimize the number of bits set in an AND
immediate, but that doesn't always match the available ARM instructions.
In Thumb1 mode, prefer uxtb or uxth where possible; otherwise, prefer
a two-instruction sequence movs+ands or movs+bics.

Some potential improvements outlined in
ARMTargetLowering::targetShrinkDemandedConstant, but seems to work
pretty well already.

The ARMISelDAGToDAG fix ensures we don't generate an invalid UBFX
instruction due to a larger-than-expected mask. (It's orthogonal, in
some sense, but as far as I can tell it's either impossible or nearly
impossible to reproduce the bug without this change.)

According to my testing, this seems to consistently improve codesize by
a small amount by forming bic more often for ISD::AND with an immediate.

Differential Revision: https://reviews.llvm.org/D50030



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339472 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-10 21:21:53 +00:00
Sam Parker c709c56b9a [ARM] Disallow zexts in ARMCodeGenPrepare
Enabling ARMCodeGenPrepare by default caused a whole load of
failures. This is due to zexts and truncs not being handled properly.
ZExts are messy so it's just easier to disable for now and truncs
are allowed only as 'sinks'. I still need to figure out why allowing
them as 'sources' causes so many failures. The other main changes are
that we are explicit in the types that we converting to, it's now
always 'TypeSize'. Type support is also now performed while checking
for valid opcodes as it unnecessarily complicated having the checks
are different stages.
    
I've moved the tests around too, so we have the zext and truncs in
their own file as well as the overflowing opcode tests.

Differential Revision: https://reviews.llvm.org/D50518


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339432 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-10 13:57:13 +00:00
Evandro Menezes 5e77ae5ff5 [ARM] Replace processor check with feature
Add new feature, `FeatureUseWideStrideVFP`, that replaces the need for a
processor check.  Otherwise, NFC.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339354 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-09 16:13:24 +00:00
Sjoerd Meijer cc67ca7ead [ARM] FP16: codegen support for VTRN
Differential Revision: https://reviews.llvm.org/D50454


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339340 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-09 12:45:09 +00:00