Skip to content

Commit

Permalink
Add subclass data to the FoldingSetNode for MemIntrinsicSDNodes.
Browse files Browse the repository at this point in the history
Not having the subclass data on an MemIntrinsicSDNodes means it was possible
to try to fold 2 nodes with the same operands but differing MMO flags. This
would trip an assertion when trying to refine the alignment between the 2
MachineMemOperands.

Differential Revision: https://reviews.llvm.org/D38898

llvm-svn: 316737
  • Loading branch information
Sean Fertile committed Oct 27, 2017
1 parent 79048e4 commit 57d46b8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Expand Up @@ -336,6 +336,14 @@ class SelectionDAG {
.getRawSubclassData();
}

template <typename SDNodeTy>
static uint16_t getSyntheticNodeSubclassData(unsigned Opc, unsigned Order,
SDVTList VTs, EVT MemoryVT,
MachineMemOperand *MMO) {
return SDNodeTy(Opc, Order, DebugLoc(), VTs, MemoryVT, MMO)
.getRawSubclassData();
}

void createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
assert(!Node->OperandList && "Node already has operands");
SDUse *Ops = OperandRecycler.allocate(
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Expand Up @@ -5746,6 +5746,8 @@ SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl,
if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opcode, VTList, Ops);
ID.AddInteger(getSyntheticNodeSubclassData<MemIntrinsicSDNode>(
Opcode, dl.getIROrder(), VTList, MemVT, MMO));
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
void *IP = nullptr;
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
Expand Down
37 changes: 37 additions & 0 deletions llvm/test/CodeGen/PowerPC/MMO-flags-assertion.ll
@@ -0,0 +1,37 @@
; RUN: llc < %s -mtriple powerpc64le-unknown-linux-gnu

; void llvm::MachineMemOperand::refineAlignment(const llvm::MachineMemOperand*):
; Assertion `MMO->getFlags() == getFlags() && "Flags mismatch !"' failed.

declare void @_Z3fn11F(%class.F* byval align 8) local_unnamed_addr
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
declare signext i32 @_ZN1F11isGlobalRegEv(%class.F*) local_unnamed_addr
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @_Z10EmitLValuev(%class.F* sret) local_unnamed_addr
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)

%class.F = type { i32, i64, i8, [64 x i8], i8, i32* }

define signext i32 @_Z29EmitOMPAtomicSimpleUpdateExpr1F(%class.F* byval align 8 %p1) local_unnamed_addr {
entry:
call void @_Z3fn11F(%class.F* byval nonnull align 8 %p1)
%call = call signext i32 @_ZN1F11isGlobalRegEv(%class.F* nonnull %p1)
ret i32 %call
}

define void @_Z3fn2v() local_unnamed_addr {
entry:
%agg.tmp1 = alloca %class.F, align 8
%XLValue = alloca %class.F, align 8
%0 = bitcast %class.F* %XLValue to i8*
call void @llvm.lifetime.start.p0i8(i64 96, i8* nonnull %0)
call void @_Z10EmitLValuev(%class.F* nonnull sret %XLValue)
%1 = bitcast %class.F* %agg.tmp1 to i8*
call void @llvm.lifetime.start.p0i8(i64 96, i8* nonnull %1)
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %1, i8* nonnull %0, i64 96, i32 8, i1 false)
call void @_Z3fn11F(%class.F* byval nonnull align 8 %XLValue)
%call.i = call signext i32 @_ZN1F11isGlobalRegEv(%class.F* nonnull %agg.tmp1)
call void @llvm.lifetime.end.p0i8(i64 96, i8* nonnull %1)
call void @llvm.lifetime.end.p0i8(i64 96, i8* nonnull %0)
ret void
}

0 comments on commit 57d46b8

Please sign in to comment.