diff --git a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp --- a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp +++ b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp @@ -385,6 +385,10 @@ } unsigned HexagonOptAddrMode::getOffsetOpPosition(MachineInstr *MI) { + assert( + (HII->getAddrMode(*MI) == HexagonII::BaseImmOffset) && + "Looking for an offset in non-BaseImmOffset addressing mode instruction"); + const MCInstrDesc &MID = MI->getDesc(); switch (MI->getOpcode()) { // vgather pseudos are mayLoad and mayStore @@ -413,8 +417,9 @@ NodeAddr SN = UN.Addr->getOwner(*DFG); MachineInstr *MI = SN.Addr->getCode(); const MCInstrDesc &MID = MI->getDesc(); - if ((!MID.mayLoad() && !MID.mayStore())) - return false; + if ((!MID.mayLoad() && !MID.mayStore()) || + HII->getAddrMode(*MI) != HexagonII::BaseImmOffset) + return false; MachineOperand BaseOp = MI->getOperand(getBaseOpPosition(MI)); diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsV65.td b/llvm/lib/Target/Hexagon/HexagonPatternsV65.td --- a/llvm/lib/Target/Hexagon/HexagonPatternsV65.td +++ b/llvm/lib/Target/Hexagon/HexagonPatternsV65.td @@ -7,7 +7,8 @@ //===----------------------------------------------------------------------===// multiclass vgathermh { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = HalfWordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, IntRegs:$Rt, ModRegs:$Mu, RC:$Vv), @@ -16,7 +17,8 @@ } multiclass vgathermw { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = WordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, IntRegs:$Rt, ModRegs:$Mu, RC:$Vv), @@ -25,7 +27,8 @@ } multiclass vgathermhw { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = HalfWordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, IntRegs:$Rt, ModRegs:$Mu, RC:$Vv), @@ -38,7 +41,8 @@ defm V6_vgathermhw_pseudo : vgathermhw; multiclass vgathermhq { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = HalfWordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu, @@ -48,7 +52,8 @@ } multiclass vgathermwq { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = WordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu, @@ -58,7 +63,8 @@ } multiclass vgathermhwq { - let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in + let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, + mayStore = 1, addrMode = BaseImmOffset, accessSize = HalfWordAccess in def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ), (ins IntRegs:$_dst_, s4_0Imm:$Ii, RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu, diff --git a/llvm/test/CodeGen/Hexagon/addrmode-opt-assert.mir b/llvm/test/CodeGen/Hexagon/addrmode-opt-assert.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/addrmode-opt-assert.mir @@ -0,0 +1,24 @@ +# RUN: llc -march=hexagon -mcpu=hexagonv62 -run-pass amode-opt %s -o - +# REQUIRES: asserts +# +# This test merely checks if the pass that optimizes addressing modes in the +# hexagon backend doesn't crash when the following code is presented to it. +# +# This is a testcase reduced from code generated by the Halide compiler for a +# Halide pipeline. This code was causing the pass 'amode-opt' to crash because +# it was looking for the third operand (offset) in the following instruction +# that does not, in fact, have a third operand. +# +# $r1 = L2_loadw_locked $r1 +# +# Check that this doesn't crash. + + +name: fred +tracksRegLiveness: true +body: | + bb.0: + liveins: $r0 + $r1 = A2_addi $r0, 4 + $r1 = L2_loadw_locked $r1 +...