diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-09-01 18:27:51 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-09-01 18:27:51 +0000 |
commit | 4a0a18af4a9a47466a6077a158387ba4f57bf636 (patch) | |
tree | c147d444f5f533499a7252ed62065e83b92fbd01 /test/CodeGen/ARM | |
parent | 2f25d9b9334662e846460e98a8fe2dae4f233068 (diff) | |
download | external_llvm-4a0a18af4a9a47466a6077a158387ba4f57bf636.zip external_llvm-4a0a18af4a9a47466a6077a158387ba4f57bf636.tar.gz external_llvm-4a0a18af4a9a47466a6077a158387ba4f57bf636.tar.bz2 |
Permit remat of partial register defs when it is safe.
An instruction may define part of a register where the other bits are
undefined. In that case, it is safe to rematerialize the instruction.
For example:
%vreg2:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg, %vreg2<imp-def>
The extra <imp-def> operand indicates that the instruction does not read
the other parts of the virtual register, so a remat is safe.
This patch simply allows multiple def operands for the virtual register.
It is MI->readsVirtualRegister() that determines if we depend on a
previous value so remat is impossible.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138953 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ARM')
-rw-r--r-- | test/CodeGen/ARM/subreg-remat.ll | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/subreg-remat.ll b/test/CodeGen/ARM/subreg-remat.ll index cf45c03..993d7ec 100644 --- a/test/CodeGen/ARM/subreg-remat.ll +++ b/test/CodeGen/ARM/subreg-remat.ll @@ -26,3 +26,27 @@ define void @f1(float %x, <2 x float>* %p) { store <2 x float> %v2, <2 x float>* %p, align 8 ret void } + +; On the other hand, when the partial redef doesn't read the full register +; because the bits are undef, we should rematerialize. The vector is now built +; like this: +; +; %vreg2:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg, %vreg2<imp-def>; mem:LD4[ConstantPool] +; +; The extra <imp-def> operand indicates that the instruction fully defines the +; virtual register. It doesn't read the old value. +; +; CHECK: f2 +; CHECK: vldr.32 s0, LCPI +; The vector must not be spilled: +; CHECK-NOT: vstr.64 +; CHECK: asm clobber d0 +; But instead rematerialize after the asm: +; CHECK: vldr.32 [[S0:s[0-9]+]], LCPI +; CHECK: vstr.64 [[D0:d[0-9]+]], [r0] +define void @f2(<2 x float>* %p) { + %v2 = insertelement <2 x float> undef, float 0x400921FB60000000, i32 0 + %y = call double asm sideeffect "asm clobber $0", "=w,0,~{d1},~{d2},~{d3},~{d4},~{d5},~{d6},~{d7},~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15},~{d16},~{d17},~{d18},~{d19},~{d20},~{d21},~{d22},~{d23},~{d24},~{d25},~{d26},~{d27},~{d28},~{d29},~{d30},~{d31}"(<2 x float> %v2) nounwind + store <2 x float> %v2, <2 x float>* %p, align 8 + ret void +} |