llvm-6502/include/llvm/CodeGen
Adam Nemet 726942c8bb [ISel] Keep matching state consistent when folding during X86 address match
In the X86 backend, matching an address is initiated by the 'addr' complex
pattern and its friends.  During this process we may reassociate and-of-shift
into shift-of-and (FoldMaskedShiftToScaledMask) to allow folding of the
shift into the scale of the address.

However as demonstrated by the testcase, this can trigger CSE of not only the
shift and the AND which the code is prepared for but also the underlying load
node.  In the testcase this node is sitting in the RecordedNode and MatchScope
data structures of the matcher and becomes a deleted node upon CSE.  Returning
from the complex pattern function, we try to access it again hitting an assert
because the node is no longer a load even though this was checked before.

Now obviously changing the DAG this late is bending the rules but I think it
makes sense somewhat.  Outside of addresses we prefer and-of-shift because it
may lead to smaller immediates (FoldMaskAndShiftToScale is an even better
example because it create a non-canonical node).  We currently don't recognize
addresses during DAGCombiner where arguably this canonicalization should be
performed.  On the other hand, having this in the matcher allows us to cover
all the cases where an address can be used in an instruction.

I've also talked a little bit to Dan Gohman on llvm-dev who added the RAUW for
the new shift node in FoldMaskedShiftToScaledMask.  This RAUW is responsible
for initiating the recursive CSE on users
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-September/076903.html) but it
is not strictly necessary since the shift is hooked into the visited user.  Of
course it's safer to keep the DAG consistent at all times (e.g. for accurate
number of uses, etc.).

So rather than changing the fundamentals, I've decided to continue along the
previous patches and detect the CSE.  This patch installs a very targeted
DAGUpdateListener for the duration of a complex-pattern match and updates the
matching state accordingly.  (Previous patches used HandleSDNode to detect the
CSE but that's not practical here).  The listener is only installed on X86.

I tested that there is no measurable overhead due to this while running
through the spec2k BC files with llc.  The only thing we pay for is the
creation of the listener.  The callback never ever triggers in spec2k since
this is a corner case.

Fixes rdar://problem/18206171

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219009 91177308-0d34-0410-b5e6-96231b3b80d8
2014-10-03 20:00:34 +00:00
..
PBQP [PBQP] Update doxygen comment style to match the rest of the file. NFC. 2014-10-02 04:21:27 +00:00
Analysis.h Refactor duplicated code. 2014-07-30 19:42:16 +00:00
AsmPrinter.h Debug info: Infrastructure to support debug locations for fragmented 2014-08-01 22:11:58 +00:00
CalcSpillWeights.h CalcSpillWeights: allow overidding the spill weight normalizing function 2013-11-11 19:56:14 +00:00
CallingConvLower.h [mips] Add CCValAssign::[ASZ]ExtUpper and CCPromoteToUpperBitsInType and handle struct's correctly on big-endian N32/N64 return values. 2014-09-25 12:15:05 +00:00
CommandFlags.h Replace -use-init-array with -use-ctors. 2014-09-02 13:54:53 +00:00
DAGCombine.h Refactor DAGCombinerInfo. Change the different booleans that indicate if we are before or after different runs of DAGCo, with the CombineLevel enum. 2012-12-27 06:47:41 +00:00
DFAPacketizer.h Cleanup: Delete seemingly unused reference to MachineDominatorTree from ScheduleDAGInstrs. 2014-08-20 20:57:26 +00:00
EdgeBundles.h [modules] "Specialize" a function by actually specializing a function template 2014-04-24 18:27:29 +00:00
FastISel.h [FastISel][AArch64] Add lowering support for frem. 2014-09-15 22:07:49 +00:00
FunctionLoweringInfo.h Optimize sext/zext insertion algorithm in back-end. 2014-09-19 05:30:35 +00:00
GCMetadata.h Use unique_ptr to manage ownership of GCStrategy objects in GCMetadata 2014-04-15 05:34:49 +00:00
GCMetadataPrinter.h
GCs.h Test commit: Remove trailing whitespace. 2014-03-10 22:24:07 +00:00
GCStrategy.h Use unique_ptr to manage ownership of GCFunctionInfos in GCStrategy 2014-04-15 06:07:26 +00:00
IntrinsicLowering.h Rename some member variables from TD to DL. 2014-02-18 15:33:12 +00:00
ISDOpcodes.h CodeGen: extend f16 conversions to permit types > float. 2014-07-17 10:51:23 +00:00
JumpInstrTables.h Escape "@function" with \verbatim. [-Wdocumentation] 2014-06-08 23:25:02 +00:00
LatencyPriorityQueue.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
LexicalScopes.h Repace SmallPtrSet with SmallPtrSetImpl in function arguments to avoid needing to mention the size. 2014-08-21 05:55:13 +00:00
LinkAllAsmWriterComponents.h Add a GC plugin for Erlang 2013-03-25 13:47:46 +00:00
LinkAllCodegenComponents.h [C++] Use 'nullptr'. 2014-04-24 06:44:33 +00:00
LiveInterval.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
LiveIntervalAnalysis.h Canonicalize header guards into a common format. 2014-08-13 16:26:38 +00:00
LiveIntervalUnion.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
LivePhysRegs.h Canonicalize header guards into a common format. 2014-08-13 16:26:38 +00:00
LiveRangeEdit.h Remove unnecessary getTarget call now that the subtarget is cached 2014-09-03 20:36:26 +00:00
LiveRegMatrix.h [C++11] Replace OwningPtr with std::unique_ptr in places where it doesn't break the API. 2014-04-21 09:34:48 +00:00
LiveStackAnalysis.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
LiveVariables.h CodeGen/LiveVariables: hoist out code in nested loops 2014-08-25 01:59:49 +00:00
MachineBasicBlock.h Fix missing const 2014-07-02 06:45:26 +00:00
MachineBlockFrequencyInfo.h blockfreq: Remove unnecessary template parameters 2014-04-11 23:21:02 +00:00
MachineBranchProbabilityInfo.h blockfreq: Use const in MachineBlockFrequencyInfo 2014-03-25 18:01:32 +00:00
MachineCombinerPattern.h MachineCombiner Pass for selecting faster instruction 2014-08-03 21:35:39 +00:00
MachineConstantPool.h CodeGen: Add a getSectionKind method to MachineConstantPoolEntry 2014-07-14 22:06:29 +00:00
MachineDominanceFrontier.h Try to fix MSVC build 2014-07-12 23:09:02 +00:00
MachineDominators.h [MachineDominatorTree] Provide a method to inform a MachineDominatorTree that a 2014-08-13 21:00:07 +00:00
MachineFrameInfo.h musttail: Forward regparms of variadic functions on x86_64 2014-08-29 21:42:08 +00:00
MachineFunction.h Have setSubtarget take a const subtarget. 2014-09-26 01:28:13 +00:00
MachineFunctionAnalysis.h [C++11] Add 'override' keyword to virtual methods that override their base class. 2014-03-07 09:26:03 +00:00
MachineFunctionPass.h [C++11] Add 'override' keyword to virtual methods that override their base class. 2014-03-07 09:26:03 +00:00
MachineInstr.h Move the complex address expression out of DIVariable and into an extra 2014-10-01 18:55:02 +00:00
MachineInstrBuilder.h Move the complex address expression out of DIVariable and into an extra 2014-10-01 18:55:02 +00:00
MachineInstrBundle.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
MachineJumpTableInfo.h Sort the #include lines for the include/... tree with the script. 2012-12-03 17:02:12 +00:00
MachineLoopInfo.h [C++11] Add 'override' keyword to virtual methods that override their base class. 2014-03-07 09:26:03 +00:00
MachineMemOperand.h AA metadata refactoring (introduce AAMDNodes) 2014-07-24 12:16:19 +00:00
MachineModuleInfo.h Move the complex address expression out of DIVariable and into an extra 2014-10-01 18:55:02 +00:00
MachineModuleInfoImpls.h Rename virtual table anchors from Anchor() to anchor() for consistency with the rest of the tree. 2012-09-26 06:36:36 +00:00
MachineOperand.h Add MachineOperand::ChangeToFPImmediate and setFPImm 2014-09-28 19:24:59 +00:00
MachinePassRegistry.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
MachinePostDominators.h Fix typos in comments, NFC 2014-08-29 21:53:01 +00:00
MachineRegionInfo.h Templatify RegionInfo so it works on MachineBasicBlocks 2014-07-19 18:29:29 +00:00
MachineRegisterInfo.h CodeGen: switch raw array to std::vector 2014-08-25 00:28:31 +00:00
MachineScheduler.h Cleanup: Delete seemingly unused reference to MachineDominatorTree from ScheduleDAGInstrs. 2014-08-20 20:57:26 +00:00
MachineSSAUpdater.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
MachineTraceMetrics.h Canonicalize header guards into a common format. 2014-08-13 16:26:38 +00:00
MachineValueType.h Teach the AArch64 backend about v4f16 and v8f16 2014-08-27 16:16:04 +00:00
MachORelocation.h Fix include guards so they exactly match file names. 2013-01-10 00:45:19 +00:00
Passes.h Rename AtomicExpandLoadLinked into AtomicExpand 2014-08-21 21:50:01 +00:00
PseudoSourceValue.h Fix broken build of llvm using clang. 2014-04-15 08:10:46 +00:00
RegAllocPBQP.h unique_ptrify PBQPBuilder::build 2014-09-02 17:42:01 +00:00
RegAllocRegistry.h Fix include guards so they exactly match file names. 2013-01-10 00:45:19 +00:00
RegisterClassInfo.h [C++11] Replace OwningPtr with std::unique_ptr in places where it doesn't break the API. 2014-04-21 09:34:48 +00:00
RegisterPressure.h Move remaining LLVM_ENABLE_DUMP conditionals out of the headers 2014-07-01 21:19:13 +00:00
RegisterScavenging.h Changed the liveness tracking in the RegisterScavenger 2014-08-04 23:07:49 +00:00
ResourcePriorityQueue.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-15 06:32:26 +00:00
RuntimeLibcalls.h CodeGen: generate single libcall for fptrunc -> f16 operations. 2014-07-17 11:12:12 +00:00
ScheduleDAG.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
ScheduleDAGInstrs.h Cleanup: Delete seemingly unused reference to MachineDominatorTree from ScheduleDAGInstrs. 2014-08-20 20:57:26 +00:00
ScheduleDFS.h Move remaining LLVM_ENABLE_DUMP conditionals out of the headers 2014-07-01 21:19:13 +00:00
ScheduleHazardRecognizer.h Add two additional hazard recognizer functions 2013-12-11 22:33:43 +00:00
SchedulerRegistry.h Fix include guards so they exactly match file names. 2013-01-10 00:45:19 +00:00
ScoreboardHazardRecognizer.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
SelectionDAG.h Move the complex address expression out of DIVariable and into an extra 2014-10-01 18:55:02 +00:00
SelectionDAGISel.h [ISel] Keep matching state consistent when folding during X86 address match 2014-10-03 20:00:34 +00:00
SelectionDAGNodes.h Repace SmallPtrSet with SmallPtrSetImpl in function arguments to avoid needing to mention the size. 2014-08-21 05:55:13 +00:00
SlotIndexes.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
StackMapLivenessAnalysis.h Canonicalize header guards into a common format. 2014-08-13 16:26:38 +00:00
StackMaps.h Add and update reset() and doInitialization() methods to MC* and passes. 2014-09-17 09:25:36 +00:00
StackProtector.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00
TargetLoweringObjectFileImpl.h CodeGen: Stick constant pool entries in COMDAT sections for WinCOFF 2014-07-14 22:57:27 +00:00
TargetSchedule.h Change MCSchedModel to be a struct of statically initialized data. 2014-09-02 17:43:54 +00:00
ValueTypes.h [C++11] More 'nullptr' conversion or in some cases just using a boolean check instead of comparing to nullptr. 2014-04-09 06:08:46 +00:00
ValueTypes.td Implement aarch64 neon instruction set AdvSIMD (Across). 2013-10-05 08:22:10 +00:00
VirtRegMap.h [C++11] More 'nullptr' conversion. In some cases just using a boolean check instead of comparing to nullptr. 2014-04-14 00:51:57 +00:00