aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2020-06-03 16:15:23 -0700
committerQuentin Colombet <qcolombet@apple.com>2020-06-03 17:10:55 -0700
commitccb3c8e8613413846d6c2f17cc1c1e2a8b6a98ef (patch)
treed83e6f69f8f7f59a4900daa8b52895109ead529f /clang/lib/Lex/ModuleMap.cpp
parenteb9ca9da3e94e0c0d5eb8d98a388e92da0df9f12 (diff)
downloadllvm-ccb3c8e8613413846d6c2f17cc1c1e2a8b6a98ef.zip
llvm-ccb3c8e8613413846d6c2f17cc1c1e2a8b6a98ef.tar.gz
llvm-ccb3c8e8613413846d6c2f17cc1c1e2a8b6a98ef.tar.bz2
[RegisterCoalescer] Update empty subranges when rematerializing
When we rematerialize a value as part of the coalescing, we may widen the register class of the destination register. When this happens, updateRegDefUses may create additional subranges to account for the wider register class. The created subranges are empty and if they are not defined by the rematerialized instruction we clean them up. However, if they are defined by the rematerialized instruction but unused, we failed to flag them as dead definition and would leave them as empty live-range. This is wrong because empty live-ranges don't interfere with anything, thus if we don't fix them, we would fail to account that the rematerialized instruction clobbers some lanes. E.g., let us consider the following pseudo code: def.lane_low64:reg128 = ldimm newdef:reg32 = COPY def.lane_low64_low32 When rematerialization happens for newdef, we end up with: newdef.lane_low64:reg128 = ldimm = use newdef.lane_low64_low32 Let's look at the live interval of newdef. Before rematerialization, we would get: newdef [defIdx, useIdx:0) 0@defIdx Right after updateRegDefUses, newdef register class is widen to reg128 and the subrange definitions will be augmented to fill the subreg that is used at the definition point, here lane_low64. The resulting live interval would be: newdef [newDefIdx, useIdx:0) 0@newDefIdx * lane_low64_high32 EMPTY * lane_low64_low32 [newDefIdx, useIdx:0) Before this patch this would be the final status of the live interval. Therefore we miss that lane_low64_high32 is actually live on the definition point of newdef. With this patch, after rematerializing, we check all the added subranges and for the ones that are defined but empty, we flag them as dead def. Thus, in that case, newdef would look like this: newdef [newDefIdx, useIdx:0) 0@newDefIdx * lane_low64_high32 [newDefIdx, newDefIdxDead) ; <-- instead of EMPTY * lane_low64_low32 [newDefIdx, useIdx:0) This fixes https://www.llvm.org/PR46154
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
0 files changed, 0 insertions, 0 deletions