forked from OSchip/llvm-project
[ARM] GlobalISel: Select G_CONSTANT with CImm operands
When selecting a G_CONSTANT to a MOVi, we need the value to be an Imm operand. We used to just leave the G_CONSTANT operand unchanged, which works in some cases (such as the GEP offsets that we create when referring to stack slots). However, in many other places the G_CONSTANTs are created with CImm operands. This patch makes sure to handle those as well, and to error out gracefully if in the end we don't end up with an Imm operand. Thanks to Oliver Stannard for reporting this issue. llvm-svn: 301162
This commit is contained in:
parent
01b880a954
commit
95a8aa93e2
|
@ -351,6 +351,18 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {
|
|||
"Expected constant to live in a GPR");
|
||||
I.setDesc(TII.get(ARM::MOVi));
|
||||
MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
|
||||
|
||||
auto &Val = I.getOperand(1);
|
||||
if (Val.isCImm()) {
|
||||
if (Val.getCImm()->getBitWidth() > 32)
|
||||
return false;
|
||||
Val.ChangeToImmediate(Val.getCImm()->getZExtValue());
|
||||
}
|
||||
|
||||
if (!Val.isImm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case G_STORE:
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
define void @test_stores() #0 { ret void }
|
||||
|
||||
define void @test_gep() { ret void }
|
||||
define void @test_constants() { ret void }
|
||||
define void @test_constant_imm() { ret void }
|
||||
define void @test_constant_cimm() { ret void }
|
||||
|
||||
define void @test_soft_fp_double() #0 { ret void }
|
||||
|
||||
|
@ -744,8 +745,8 @@ body: |
|
|||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_constants
|
||||
# CHECK-LABEL: name: test_constants
|
||||
name: test_constant_imm
|
||||
# CHECK-LABEL: name: test_constant_imm
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
selected: false
|
||||
|
@ -762,6 +763,26 @@ body: |
|
|||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_constant_cimm
|
||||
# CHECK-LABEL: name: test_constant_cimm
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
selected: false
|
||||
# CHECK: selected: true
|
||||
registers:
|
||||
- { id: 0, class: gprb }
|
||||
# CHECK: id: [[C:[0-9]+]], class: gpr
|
||||
body: |
|
||||
bb.0:
|
||||
; Adding a type on G_CONSTANT changes its operand from an Imm into a CImm.
|
||||
; We still want to see the same thing in the output though.
|
||||
%0(s32) = G_CONSTANT i32 42
|
||||
; CHECK: %[[C]] = MOVi 42, 14, _, _
|
||||
|
||||
%r0 = COPY %0(s32)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_soft_fp_double
|
||||
# CHECK-LABEL: name: test_soft_fp_double
|
||||
legalized: true
|
||||
|
|
|
@ -7,6 +7,14 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
define i32 @test_constant_return_i32() {
|
||||
; CHECK-LABEL: test_constant_return_i32:
|
||||
; CHECK: mov r0, #42
|
||||
; CHECK: bx lr
|
||||
entry:
|
||||
ret i32 42
|
||||
}
|
||||
|
||||
define zeroext i1 @test_zext_i1(i1 %x) {
|
||||
; CHECK-LABEL: test_zext_i1
|
||||
; CHECK: and r0, r0, #1
|
||||
|
|
Loading…
Reference in New Issue