[PATCH] llvm: fix crash with llvm-11 / use real phi-nodes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux