diff options
| author | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-07-29 09:16:46 +0000 |
|---|---|---|
| committer | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-07-29 09:16:46 +0000 |
| commit | d1233e857ef7dbf33a6d3dfbecad04d7a46c8a45 (patch) | |
| tree | ec8fe2fc550e815d4a38576a2f5661f958cef107 | |
| parent | da704adc2f2674a755caf866211a8553f2ba78e1 (diff) | |
| download | bcm5719-llvm-d1233e857ef7dbf33a6d3dfbecad04d7a46c8a45.tar.gz bcm5719-llvm-d1233e857ef7dbf33a6d3dfbecad04d7a46c8a45.zip | |
[Thumb] Emit Thumb move in both Thumb modes for struct_byval predicates
Summary:
The MOV/MOVT instructions being chosen for struct_byval predicates was
conditional only on Thumb2, resulting in an ARM MOV/MOVT instruction
being incorrectly emitted in Thumb1 mode. This is especially apparent
with v8-m.base targets. This patch ensures that Thumb instructions are
emitted in both Thumb modes.
Reviewers: rengolin, t.p.northover
Subscribers: llvm-commits, aemerson, rengolin
Differential Revision: https://reviews.llvm.org/D22865
llvm-svn: 277128
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/struct_byval_arm_t1_t2.ll | 29 |
2 files changed, 34 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 82c32af3b86..2571e8b9368 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -7904,6 +7904,7 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI, bool IsThumb1 = Subtarget->isThumb1Only(); bool IsThumb2 = Subtarget->isThumb2(); + bool IsThumb = Subtarget->isThumb(); if (Align & 1) { UnitSize = 1; @@ -7925,7 +7926,7 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI, // Select the correct opcode and register class for unit size load/store bool IsNeon = UnitSize >= 8; - TRC = (IsThumb1 || IsThumb2) ? &ARM::tGPRRegClass : &ARM::GPRRegClass; + TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass; if (IsNeon) VecTRC = UnitSize == 16 ? &ARM::DPairRegClass : UnitSize == 8 ? &ARM::DPRRegClass @@ -8007,12 +8008,12 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI, if ((LoopSize & 0xFFFF0000) != 0) Vtmp = MRI.createVirtualRegister(TRC); AddDefaultPred(BuildMI(BB, dl, - TII->get(IsThumb2 ? ARM::t2MOVi16 : ARM::MOVi16), + TII->get(IsThumb ? ARM::t2MOVi16 : ARM::MOVi16), Vtmp).addImm(LoopSize & 0xFFFF)); if ((LoopSize & 0xFFFF0000) != 0) AddDefaultPred(BuildMI(BB, dl, - TII->get(IsThumb2 ? ARM::t2MOVTi16 : ARM::MOVTi16), + TII->get(IsThumb ? ARM::t2MOVTi16 : ARM::MOVTi16), varEnd) .addReg(Vtmp) .addImm(LoopSize >> 16)); @@ -8027,7 +8028,7 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI, Align = MF->getDataLayout().getTypeAllocSize(C->getType()); unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align); - if (IsThumb1) + if (IsThumb) AddDefaultPred(BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci)).addReg( varEnd, RegState::Define).addConstantPoolIndex(Idx)); else diff --git a/llvm/test/CodeGen/ARM/struct_byval_arm_t1_t2.ll b/llvm/test/CodeGen/ARM/struct_byval_arm_t1_t2.ll index 0a9bc3c87f9..fc4f11e8b45 100644 --- a/llvm/test/CodeGen/ARM/struct_byval_arm_t1_t2.ll +++ b/llvm/test/CodeGen/ARM/struct_byval_arm_t1_t2.ll @@ -7,6 +7,10 @@ ;RUN: llc < %s -mtriple=thumbv5-none-linux-gnueabi -verify-machineinstrs -filetype=obj | llvm-objdump -triple thumbv5-none-linux-gnueabi -disassemble - > %t ;RUN: cat %t | FileCheck %s --check-prefix=THUMB1 ;RUN: cat %t | FileCheck %s --check-prefix=T1POST +;RUN: llc < %s -mtriple=thumbv8m.base-arm-none-eabi -verify-machineinstrs -filetype=obj | llvm-objdump -triple thumbv8m.base-arm-none-eabi -disassemble - > %t +;RUN: cat %t | FileCheck %s --check-prefix=THUMB1 +;RUN: cat %t | FileCheck %s --check-prefix=T1POST +;RUN: cat %t | FileCheck %s --check-prefix=V8MBASE ;This file contains auto generated tests for the lowering of passing structs ;byval in the arm backend. We have tests for both packed and unpacked @@ -44,6 +48,10 @@ declare void @use_J(%struct.J* byval) declare void @use_K(%struct.K* byval) %struct.L = type { [ 100 x i32 ], [ 3 x i8 ] } ; 403 bytes declare void @use_L(%struct.L* byval) +%struct.M = type { [ 64 x i8 ] } ; 64 bytes +declare void @use_M(%struct.M* byval) +%struct.N = type { [ 128 x i8 ] } ; 128 bytes +declare void @use_N(%struct.N* byval) ;ARM-LABEL: test_A_1: ;THUMB2-LABEL: test_A_1: @@ -1521,3 +1529,24 @@ declare void @use_L(%struct.L* byval) call void @use_L(%struct.L* byval align 16 %a) ret void } +;V8MBASE-LABEL: test_M: + define void @test_M() { + +;V8MBASE: ldrb r{{[0-9]+}}, {{\[}}[[BASE:r[0-9]+]]{{\]}} +;V8MBASE: adds [[BASE]], #1 +;V8MBASE-NOT: movw + entry: + %a = alloca %struct.M, align 1 + call void @use_M(%struct.M* byval align 1 %a) + ret void + } +;V8MBASE-LABEL: test_N: + define void @test_N() { + +;V8MBASE: movw r{{[0-9]+}}, #{{[0-9]+}} +;V8MBASE-NOT: b #{{[0-9]+}} + entry: + %a = alloca %struct.N, align 1 + call void @use_N(%struct.N* byval align 1 %a) + ret void + } |

