From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
To: linux-sparse@vger.kernel.org
Cc: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Subject: [PATCH] llvm: fix crash with llvm-11 / use real phi-nodes
Date: Fri, 23 Oct 2020 00:53:13 +0200 [thread overview]
Message-ID: <20201022225313.33229-1-luc.vanoostenryck@gmail.com> (raw)
sparse-llvm crashes with LLVM-11. From what I can see, it's because
LLVM-11 doesn't like anymore that an instruction is first created
unattached to a basic block (LLVMClearInsertionPosition()) and
inserted at some later step (LLVMInsertIntoBuilder()). Since the
corresponding function still exist I suppose they're working correctly
and sparse-llvm somehow misuse them. I don't know.
However, this functionality is only used to create the alloca
instructions used to simulate the phi-nodes.
So, fix this crash by using real phi instructions for the phi-nodes.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
sparse-llvm.c | 75 ++++++++++++++++++++-------------------------------
1 file changed, 29 insertions(+), 46 deletions(-)
diff --git a/sparse-llvm.c b/sparse-llvm.c
index c7a9fbb7eee1..c984dc877a61 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -826,37 +826,14 @@ static void output_op_call(struct function *fn, struct instruction *insn)
static void output_op_phisrc(struct function *fn, struct instruction *insn)
{
- LLVMValueRef v;
- struct instruction *phi;
-
- assert(insn->target->priv == NULL);
-
- /* target = src */
- v = get_operand(fn, insn->type, insn->phi_src);
-
- FOR_EACH_PTR(insn->phi_users, phi) {
- LLVMValueRef load, ptr;
-
- assert(phi->opcode == OP_PHI);
- /* phi must be load from alloca */
- load = phi->target->priv;
- assert(LLVMGetInstructionOpcode(load) == LLVMLoad);
- ptr = LLVMGetOperand(load, 0);
- /* store v to alloca */
- LLVMBuildStore(fn->builder, v, ptr);
- } END_FOR_EACH_PTR(phi);
+ insn->src->priv = get_operand(fn, insn->type, insn->src);
}
static void output_op_phi(struct function *fn, struct instruction *insn)
{
- LLVMValueRef load = insn->target->priv;
-
- /* forward load */
- assert(LLVMGetInstructionOpcode(load) == LLVMLoad);
- /* forward load has no parent block */
- assert(!LLVMGetInstructionParent(load));
- /* finalize load in current block */
- LLVMInsertIntoBuilder(fn->builder, load);
+ LLVMTypeRef dst_type = insn_symbol_type(insn);
+
+ insn->target->priv = LLVMBuildPhi(fn->builder, dst_type, "");
}
static void output_op_ptrcast(struct function *fn, struct instruction *insn)
@@ -1161,30 +1138,11 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
static int nr_bb;
LLVMBasicBlockRef bbr;
char bbname[32];
- struct instruction *insn;
sprintf(bbname, "L%d", nr_bb++);
bbr = LLVMAppendBasicBlock(function.fn, bbname);
bb->priv = bbr;
-
- /* allocate alloca for each phi */
- FOR_EACH_PTR(bb->insns, insn) {
- LLVMBasicBlockRef entrybbr;
- LLVMTypeRef phi_type;
- LLVMValueRef ptr;
-
- if (!insn->bb || insn->opcode != OP_PHI)
- continue;
- /* insert alloca into entry block */
- entrybbr = LLVMGetEntryBasicBlock(function.fn);
- LLVMPositionBuilderAtEnd(function.builder, entrybbr);
- phi_type = insn_symbol_type(insn);
- ptr = LLVMBuildAlloca(function.builder, phi_type, "");
- /* emit forward load for phi */
- LLVMClearInsertionPosition(function.builder);
- insn->target->priv = LLVMBuildLoad(function.builder, ptr, "phi");
- } END_FOR_EACH_PTR(insn);
}
END_FOR_EACH_PTR(bb);
@@ -1194,6 +1152,31 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
output_bb(&function, bb);
}
END_FOR_EACH_PTR(bb);
+
+ FOR_EACH_PTR(ep->bbs, bb) { // complete the OP_PHIs
+ struct instruction *insn;
+
+ FOR_EACH_PTR(bb->insns, insn) {
+ pseudo_t phi;
+
+ if (!insn->bb || insn->opcode != OP_PHI)
+ continue;
+
+ FOR_EACH_PTR(insn->phi_list, phi) {
+ struct instruction *phisrc;
+ LLVMBasicBlockRef bref;
+ LLVMValueRef vref;
+
+ if (phi == VOID)
+ continue;
+
+ phisrc = phi->def;
+ bref = phisrc->bb->priv;
+ vref = phisrc->src->priv;
+ LLVMAddIncoming(insn->target->priv, &vref, &bref, 1);
+ } END_FOR_EACH_PTR(phi);
+ } END_FOR_EACH_PTR(insn);
+ } END_FOR_EACH_PTR(bb);
}
static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym)
base-commit: 2d3af347e4a217f95b4f939fed9e76541d8b72f2
--
2.28.0
reply other threads:[~2020-10-22 22:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201022225313.33229-1-luc.vanoostenryck@gmail.com \
--to=luc.vanoostenryck@gmail.com \
--cc=linux-sparse@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).