Skip to content

[SOL] Prevent breaking ISelDAG connectivity on replacing loads by con… #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,47 @@ void BPFDAGToDAGISel::PreprocessLoad(SDNode *Node,

LLVM_DEBUG(dbgs() << "Replacing load of size " << size << " with constant "
<< val << '\n');

/* Some load nodes have edges from TokenFactor nodes. In this case
replacing the load with a constant makes the DAG disconnected.
The following checks if any of the load operands are TokenFactor
nodes, and if another TokenFactor is a user of the load, the
operand TokenFactor is connected to the user, so that the DAG
remains connected after replacing the load node by a constant.
*/
for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) {
const SDValue &OpV = Node->getOperand(I);
SDNode *Op = OpV.getNode();
if (Op->getOpcode() == ISD::TokenFactor) {
for (SDNode::use_iterator UI = Node->use_begin(), UE = Node->use_end(); UI != UE; ++UI) {
SDUse &Use = UI.getUse();
SDNode *User = Use.getUser();
if (User->getOpcode() == ISD::TokenFactor) {
SmallVector<SDValue, 8> ExtendedOps;
bool NotExtended = true;
for (unsigned UOI = 0, UOE = User->getNumOperands(); UOI != UOE; ++UOI) {
const SDValue &Operand = User->getOperand(UOI);
if (OpV == Operand) {
NotExtended = false;
break;
}
ExtendedOps.push_back(Operand);
}
if (NotExtended) {
ExtendedOps.push_back(OpV);
SDValue ExtendedTokenFactor = CurDAG->getTokenFactor(SDLoc(User), ExtendedOps);
I--;
SDValue From[] = {SDValue(User, 0)};
SDValue To[] = {ExtendedTokenFactor};
CurDAG->ReplaceAllUsesOfValuesWith(From, To, 1);
I++;
CurDAG->DeleteNode(User);
}
}
}
}
}

SDValue NVal = CurDAG->getConstant(val, DL, LD->getValueType(0));

// After replacement, the current node is dead, we need to
Expand Down
35 changes: 35 additions & 0 deletions llvm/test/CodeGen/BPF/preprocess-loads.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
; RUN: llc -O2 -march=bpfel --mattr=+solana -filetype=asm < %s | FileCheck --check-prefix=CHECK %s

%Pool = type <{ [0 x i8], [32 x i8], [0 x i8], i8, [0 x i8], [10 x %Decimal], [0 x i8] }>
%Decimal = type { [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32] }

@0 = private unnamed_addr constant <{ [16 x i8] }> <{ [16 x i8] c"\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF" }>, align 4

declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #5

; optbug::Pool::initialize
; Function Attrs: nofree noinline nounwind willreturn
define internal fastcc void @_ZN6optbug4Pool10initialize17h656ab4e5f05591beE(%Pool* noalias nocapture align 1 dereferenceable(193) %self, [32 x i8]* noalias nocapture readonly align 1 dereferenceable(32) %seed, i8 %bump) unnamed_addr #2 {
start:
%0 = getelementptr inbounds [32 x i8], [32 x i8]* %seed, i64 0, i64 0
%self56 = getelementptr inbounds %Pool, %Pool* %self, i64 0, i32 0, i64 0
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(32) %self56, i8* nonnull align 1 dereferenceable(32) %0, i64 32, i1 false)
%1 = getelementptr inbounds %Pool, %Pool* %self, i64 0, i32 3
store i8 %bump, i8* %1, align 1
%2 = getelementptr inbounds %Pool, %Pool* %self, i64 0, i32 5, i64 1
%3 = bitcast %Decimal* %2 to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(16) %3, i8* nonnull align 4 dereferenceable(16) getelementptr inbounds (<{ [16 x i8] }>, <{ [16 x i8] }>* @0, i64 0, i32 0, i64 0), i64 16, i1 false)
ret void
}

; CHECK: *(u64 *)(r1 + 24) = r4
; CHECK: *(u64 *)(r1 + 16) = r4
; CHECK: *(u64 *)(r1 + 8) = r4
; CHECK: *(u64 *)(r1 + 0) = r2
; CHECK: *(u8 *)(r1 + 32) = r3

attributes #2 = { nofree noinline nounwind willreturn "target-cpu"="generic" }

!llvm.module.flags = !{!0}

!0 = !{i32 7, !"PIC Level", i32 2}
1 change: 1 addition & 0 deletions llvm/test/tools/lto/hide-linkonce-odr.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
; XFAIL: darwin
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce

Expand Down
1 change: 1 addition & 0 deletions llvm/test/tools/lto/opt-level.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
; XFAIL: darwin
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.o
; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O0 %s
Expand Down
1 change: 1 addition & 0 deletions llvm/test/tools/lto/print-stats.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
; XFAIL: darwin
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -stats -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=STATS %s
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=NO_STATS %s
Expand Down