diff options
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonConstExtenders.cpp | 44 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/cext-opt-stack-no-rr.mir | 35 |
2 files changed, 77 insertions, 2 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonConstExtenders.cpp b/llvm/lib/Target/Hexagon/HexagonConstExtenders.cpp index 415800088d9..27b0906f229 100644 --- a/llvm/lib/Target/Hexagon/HexagonConstExtenders.cpp +++ b/llvm/lib/Target/Hexagon/HexagonConstExtenders.cpp @@ -1396,10 +1396,50 @@ void HCE::assignInits(const ExtRoot &ER, unsigned Begin, unsigned End, AssignmentMap::iterator F = IMap.find({EV, ExtExpr()}); if (F == IMap.end()) continue; + // Finally, check if all extenders have the same value as the initializer. - auto SameValue = [&EV,this](unsigned I) { + // Make sure that extenders that are a part of a stack address are not + // merged with those that aren't. Stack addresses need an offset field + // (to be used by frame index elimination), while non-stack expressions + // can be replaced with forms (such as rr) that do not have such a field. + // Example: + // + // Collected 3 extenders + // =2. imm:0 off:32968 bb#2: %7 = ## + __ << 0, def + // 0. imm:0 off:267 bb#0: __ = ## + SS#1 << 0 + // 1. imm:0 off:267 bb#1: __ = ## + SS#1 << 0 + // Ranges + // 0. [-756,267]a1+0 + // 1. [-756,267]a1+0 + // 2. [201,65735]a1+0 + // RangeMap + // [-756,267]a1+0 -> 0 1 + // [201,65735]a1+0 -> 2 + // IMap (before fixup) = { + // [imm:0 off:267, ## + __ << 0] -> { 2 } + // [imm:0 off:267, ## + SS#1 << 0] -> { 0 1 } + // } + // IMap (after fixup) = { + // [imm:0 off:267, ## + __ << 0] -> { 2 0 1 } + // [imm:0 off:267, ## + SS#1 << 0] -> { } + // } + // Inserted def in bb#0 for initializer: [imm:0 off:267, ## + __ << 0] + // %12:intregs = A2_tfrsi 267 + // + // The result was + // %12:intregs = A2_tfrsi 267 + // S4_pstorerbt_rr %3, %12, %stack.1, 0, killed %4 + // Which became + // r0 = #267 + // if (p0.new) memb(r0+r29<<#4) = r2 + + bool IsStack = any_of(F->second, [this](unsigned I) { + return Extenders[I].Expr.Rs.isSlot(); + }); + auto SameValue = [&EV,this,IsStack](unsigned I) { const ExtDesc &ED = Extenders[I]; - return ExtValue(ED).Offset == EV.Offset; + return ED.Expr.Rs.isSlot() == IsStack && + ExtValue(ED).Offset == EV.Offset; }; if (all_of(P.second, SameValue)) { F->second.insert(P.second.begin(), P.second.end()); diff --git a/llvm/test/CodeGen/Hexagon/cext-opt-stack-no-rr.mir b/llvm/test/CodeGen/Hexagon/cext-opt-stack-no-rr.mir new file mode 100644 index 00000000000..f743ddf8e2e --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/cext-opt-stack-no-rr.mir @@ -0,0 +1,35 @@ +# RUN: llc -march=hexagon -run-pass hexagon-cext-opt -hexagon-cext-threshold=1 -o - %s | FileCheck %s + +# Make sure that the stores to the stack slot are not converted into rr forms. +# CHECK: %[[REG:[0-9]+]]:intregs = PS_fi %stack.0, 267 +# CHECK: S2_pstorerbt_io %{{[0-9]+}}, %[[REG]], 0 +# CHECK: S2_pstorerbt_io %{{[0-9]+}}, %[[REG]], 0 + +--- +name: fred +stack: + - { id: 0, type: default, size: 272, alignment: 4 } +body: | + bb.0: + successors: %bb.1, %bb.2 + + %0:intregs = IMPLICIT_DEF + %1:intregs = L2_loadrub_io killed %0:intregs, 0 :: (load 1 from `i8* undef`, align 2) + %2:predregs = C2_cmpeqi %1:intregs, 5 + %3:intregs = A2_tfrsi 0 + S2_pstorerbt_io %2:predregs, %stack.0, 267, killed %3:intregs :: (store 1 into %stack.0) + J2_jumpt %2:predregs, %bb.2, implicit-def $pc + + bb.1: + successors: %bb.2 + + %4:predregs = C2_cmpeqi %1:intregs, 6 + %5:intregs = A2_tfrsi 2 + S2_pstorerbt_io %4:predregs, %stack.0, 267, killed %5:intregs :: (store 1 into %stack.0) + + bb.2: + %6:intregs = A2_tfrsi 32968 + S2_storerh_io %stack.0, 0, killed %6:intregs :: (store 2 into %stack.0, align 4) + PS_jmpret $r31, implicit-def dead $pc +... + |