From: Diana Picus Date: Thu, 28 Mar 2019 09:09:36 +0000 (+0000) Subject: [ARM GlobalISel] Fix G_STORE with s1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b94dc88e01c4ae440e3cafd70b1edcfbd07dcb97;p=llvm [ARM GlobalISel] Fix G_STORE with s1 G_STORE for 1-bit values uses a STRBi12, which stores the whole byte. Zero out the undefined bits before writing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357154 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstructionSelector.cpp b/lib/Target/ARM/ARMInstructionSelector.cpp index d0b63d676da..6df74eca6ea 100644 --- a/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/lib/Target/ARM/ARMInstructionSelector.cpp @@ -1048,6 +1048,24 @@ bool ARMInstructionSelector::select(MachineInstr &I, if (NewOpc == G_LOAD || NewOpc == G_STORE) return false; + if (ValSize == 1 && NewOpc == Opcodes.STORE8) { + // Before storing a 1-bit value, make sure to clear out any unneeded bits. + unsigned OriginalValue = I.getOperand(0).getReg(); + + unsigned ValueToStore = MRI.createVirtualRegister(&ARM::GPRRegClass); + I.getOperand(0).setReg(ValueToStore); + + auto InsertBefore = I.getIterator(); + auto AndI = BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.AND)) + .addDef(ValueToStore) + .addUse(OriginalValue) + .addImm(1) + .add(predOps(ARMCC::AL)) + .add(condCodeOp()); + if (!constrainSelectedInstRegOperands(*AndI, TII, TRI, RBI)) + return false; + } + I.setDesc(TII.get(NewOpc)); if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH) diff --git a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir index 01b0893b96e..49f6ae6da85 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir +++ b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir @@ -671,27 +671,36 @@ registers: - { id: 1, class: gprb } - { id: 2, class: gprb } - { id: 3, class: gprb } -# CHECK: id: [[P:[0-9]+]], class: gpr -# CHECK: id: [[I8:[0-9]+]], class: gpr -# CHECK: id: [[I16:[0-9]+]], class: gpr -# CHECK: id: [[I32:[0-9]+]], class: gpr + - { id: 4, class: gprb } body: | bb.0: liveins: $r0, $r1 %0(p0) = COPY $r0 + ; CHECK: [[P:%[0-9]+]]:gpr = COPY $r0 + %3(s32) = COPY $r1 + ; CHECK: [[V32:%[0-9]+]]:gpr = COPY $r1 + + %4(s1) = G_TRUNC %3(s32) + %1(s8) = G_TRUNC %3(s32) + ; CHECK: [[V8:%[0-9]+]]:gprnopc = COPY [[V32]] + %2(s16) = G_TRUNC %3(s32) + G_STORE %4(s1), %0(p0) :: (store 1) + ; CHECK: [[V1:%[0-9]+]]:gprnopc = ANDri [[V32]], 1, 14, $noreg, $noreg + ; CHECK: STRBi12 [[V1]], [[P]], 0, 14, $noreg + G_STORE %1(s8), %0(p0) :: (store 1) - ; CHECK: STRBi12 %[[I8]], %[[P]], 0, 14, $noreg + ; CHECK: STRBi12 [[V8]], [[P]], 0, 14, $noreg G_STORE %2(s16), %0(p0) :: (store 2) - ; CHECK: STRH %[[I32]], %[[P]], $noreg, 0, 14, $noreg + ; CHECK: STRH [[V32]], [[P]], $noreg, 0, 14, $noreg G_STORE %3(s32), %0(p0) :: (store 4) - ; CHECK: STRi12 %[[I32]], %[[P]], 0, 14, $noreg + ; CHECK: STRi12 [[V32]], [[P]], 0, 14, $noreg BX_RET 14, $noreg ... diff --git a/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir b/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir index 0a6ddb352a6..132424ae7e7 100644 --- a/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir +++ b/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir @@ -1,5 +1,6 @@ # RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --- | + define void @test_s1() { ret void } define void @test_s8() { ret void } define void @test_s16() { ret void } define void @test_s32() { ret void } @@ -9,6 +10,33 @@ define void @test_load_from_stack() { ret void } ... --- +name: test_s1 +# CHECK-LABEL: name: test_s1 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } +body: | + bb.0: + liveins: $r0 + + %0(p0) = COPY $r0 + ; CHECK: %[[P:[0-9]+]]:gpr = COPY $r0 + + %1(s1) = G_LOAD %0(p0) :: (load 1) + ; CHECK: %[[V8:[0-9]+]]:rgpr = t2LDRBi12 %[[P]], 0, 14, $noreg :: (load 1) + + G_STORE %1(s1), %0(p0) :: (store 1) + ; CHECK: %[[V1:[0-9]+]]:rgpr = t2ANDri %[[V8]], 1, 14, $noreg + ; CHECK: t2STRBi12 %[[V1]], %[[P]], 0, 14, $noreg :: (store 1) + + BX_RET 14, $noreg + ; CHECK: BX_RET 14, $noreg +... +--- name: test_s8 # CHECK-LABEL: name: test_s8 legalized: true