mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 04:28:30 +00:00
Fix classof for ISD::INTRINSIC_W_CHAIN and INTRINSIC_VOID
Unfortunately, our use of the SDNode class hierarchy for INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes is somewhat broken right now. These nodes sometimes are used for memory intrinsics (those with MachineMemOperands), and sometimes not. When not, the nodes are not created as instances of MemIntrinsicSDNode, but rather created as some other subclass of SDNode using DAG::getNode. When they are memory intrinsics, they are created using DAG::getMemIntrinsicNode as instances of MemIntrinsicSDNode. MemIntrinsicSDNode is a subclass of MemSDNode, but prior to r214452, we had a non-self-consistent setup whereby MemIntrinsicSDNode::classof on INTRINSIC_W_CHAIN and INTRINSIC_VOID would return true but MemSDNode::classof on INTRINSIC_W_CHAIN and INTRINSIC_VOID would return false. In r214452, MemSDNode::classof was changed to return true for INTRINSIC_W_CHAIN and INTRINSIC_VOID, which is now self-consistent. The problem is that neither the pre-r214452 logic and the post-r214452 logic are really right. The truth is that not all INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes are instances of MemIntrinsicSDNode (or MemSDNode for that matter), and the return value from classof needs to reflect that. This was broken before r214452 (because MemIntrinsicSDNode::classof always returned true), and was broken afterward (because MemSDNode::classof also always returned true), and will now be correct. The minimal solution is to grab one of the SubclassData bits (there is one left for MemIntrinsicSDNode nodes) and use it to store whether or not a particular INTRINSIC_W_CHAIN or INTRINSIC_VOID is really an instance of MemIntrinsicSDNode or not. Doing this allows both MemIntrinsicSDNode::classof and MemSDNode::classof to return the correct answer for the underlying object for both the memory-intrinsic and non-memory-intrinsic cases. This fixes the problem that r214452 created in the SelectionDAGDumper (thanks to Matt Arsenault for pointing it out). Because PowerPC does not implement getTgtMemIntrinsic, this change breaks test/CodeGen/PowerPC/unal-altivec-wint.ll. I've XFAILed it for now, and will fix it in a follow-up commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4c9467ea5d
commit
695e914c03
@ -417,6 +417,16 @@ public:
|
||||
return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
|
||||
}
|
||||
|
||||
/// Test if this node is a memory intrinsic (with valid pointer information).
|
||||
/// INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes are sometimes created for
|
||||
/// non-memory intrinsics (with chains) that are not really instances of
|
||||
/// MemSDNode. For such nodes, we need some extra state to determine the
|
||||
/// proper classof relationship.
|
||||
bool isMemIntrinsic() const {
|
||||
return (NodeType == ISD::INTRINSIC_W_CHAIN ||
|
||||
NodeType == ISD::INTRINSIC_VOID) && ((SubclassData >> 13) & 1);
|
||||
}
|
||||
|
||||
/// isMachineOpcode - Test if this node has a post-isel opcode, directly
|
||||
/// corresponding to a MachineInstr opcode.
|
||||
bool isMachineOpcode() const { return NodeType < 0; }
|
||||
@ -1158,8 +1168,7 @@ public:
|
||||
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
|
||||
N->getOpcode() == ISD::ATOMIC_LOAD ||
|
||||
N->getOpcode() == ISD::ATOMIC_STORE ||
|
||||
N->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
|
||||
N->getOpcode() == ISD::INTRINSIC_VOID ||
|
||||
N->isMemIntrinsic() ||
|
||||
N->isTargetMemoryOpcode();
|
||||
}
|
||||
};
|
||||
@ -1288,14 +1297,14 @@ public:
|
||||
ArrayRef<SDValue> Ops, EVT MemoryVT,
|
||||
MachineMemOperand *MMO)
|
||||
: MemSDNode(Opc, Order, dl, VTs, Ops, MemoryVT, MMO) {
|
||||
SubclassData |= 1u << 13;
|
||||
}
|
||||
|
||||
// Methods to support isa and dyn_cast
|
||||
static bool classof(const SDNode *N) {
|
||||
// We lower some target intrinsics to their target opcode
|
||||
// early a node with a target opcode can be of this class
|
||||
return N->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
|
||||
N->getOpcode() == ISD::INTRINSIC_VOID ||
|
||||
return N->isMemIntrinsic() ||
|
||||
N->getOpcode() == ISD::PREFETCH ||
|
||||
N->isTargetMemoryOpcode();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
; XFAIL: *
|
||||
|
||||
declare <4 x i32> @llvm.ppc.altivec.lvx(i8*) #1
|
||||
|
||||
|
23
test/CodeGen/R600/add-debug.ll
Normal file
23
test/CodeGen/R600/add-debug.ll
Normal file
@ -0,0 +1,23 @@
|
||||
; RUN: llc < %s -march=r600 -mcpu=tahiti -debug
|
||||
; REQUIRES: asserts
|
||||
|
||||
; Check that SelectionDAGDumper does not crash on int_SI_if.
|
||||
define void @add64_in_branch(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b, i64 %c) {
|
||||
entry:
|
||||
%0 = icmp eq i64 %a, 0
|
||||
br i1 %0, label %if, label %else
|
||||
|
||||
if:
|
||||
%1 = load i64 addrspace(1)* %in
|
||||
br label %endif
|
||||
|
||||
else:
|
||||
%2 = add i64 %a, %b
|
||||
br label %endif
|
||||
|
||||
endif:
|
||||
%3 = phi i64 [%1, %if], [%2, %else]
|
||||
store i64 %3, i64 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user