[Hexagon] Account for negative offset when limiting max deviation

In getOffsetRange, Max can be set to 0 to force the extender replacement
to be at or below the original value. This would cause the new offset to
be non-negative, which is preferred for memory instructions (to reduce
the likelihood of it getting constant-extended due to predication). The
problem happens when the range is shifted by an offset (present in the
instruction being examined) and the offset is negative. The entire range
for the allowable deviation will then be strictly negative. This creates
a problem, since 0 is assumed to be a valid deviation.

llvm-svn: 316601
This commit is contained in:
Krzysztof Parzyszek 2017-10-25 18:46:40 +00:00
parent cfa171d68c
commit 27056da9a8
2 changed files with 51 additions and 2 deletions

View File

@ -1040,10 +1040,13 @@ OffsetRange HCE::getOffsetRange(Register Rb, const MachineInstr &MI) const {
unsigned L = Log2_32(A);
unsigned S = 10+L; // sint11_L
int32_t Min = -alignDown((1<<S)-1, A);
int32_t Max = 0; // Force non-negative offsets.
// The range will be shifted by Off. To prefer non-negative offsets,
// adjust Max accordingly.
int32_t Off = MI.getOperand(OffP).getImm();
int32_t Max = Off >= 0 ? 0 : -Off;
OffsetRange R = { Min, Max, A };
int32_t Off = MI.getOperand(OffP).getImm();
return R.shift(Off);
}
@ -1622,6 +1625,9 @@ bool HCE::replaceInstrExpr(const ExtDesc &ED, const ExtenderInit &ExtI,
#ifndef NDEBUG
// Make sure the output is within allowable range for uses.
OffsetRange Uses = getOffsetRange(MI.getOperand(0));
if (!Uses.contains(Diff))
dbgs() << "Diff: " << Diff << " out of range " << Uses
<< " for " << MI;
assert(Uses.contains(Diff));
#endif
MBB.erase(MI);

View File

@ -0,0 +1,43 @@
# RUN: llc -march=hexagon -run-pass hexagon-cext-opt %s -o - | FileCheck %s
# Check that this testcase does not crash.
# CHECK: L4_and_memopw_io
---
name: fred
tracksRegLiveness: true
registers:
- { id: 0, class: intregs }
- { id: 1, class: intregs }
- { id: 2, class: intregs }
- { id: 3, class: intregs }
- { id: 4, class: predregs }
- { id: 5, class: intregs }
- { id: 6, class: intregs }
body: |
bb.0:
successors: %bb.1
%0 = A2_tfrsi -360184608
%1 = L2_loadri_io %0, -1024
bb.1:
successors: %bb.2
%2 = A2_tfrsi -234944641
%3 = A2_tfrsi -360185632
L4_and_memopw_io %3, 0, %2
bb.2:
successors: %bb.3, %bb.4
%4 = IMPLICIT_DEF
J2_jumpt %4, %bb.4, implicit-def %pc
J2_jump %bb.3, implicit-def %pc
bb.3:
successors: %bb.4
bb.4:
successors: %bb.4
%5 = A2_tfrsi -234944521
%6 = A2_tfrsi -360185632
L4_and_memopw_io %6, 0, %5
...