if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
vtype = type_to_llvm_type (ctx, var->inst_vtype);
CHECK_FAILURE (ctx);
- ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
+ /* Could be already created by an OP_VPHI */
+ if (!ctx->addresses [var->dreg])
+ ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
}
}
for (ins = bb->code; ins; ins = ins->next) {
switch (ins->opcode) {
case OP_PHI:
- case OP_FPHI: {
+ case OP_FPHI:
+ case OP_VPHI: {
LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
CHECK_FAILURE (ctx);
+ if (ins->opcode == OP_VPHI) {
+ /* Treat valuetype PHI nodes as operating on the address itself */
+ g_assert (ins->klass);
+ phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
+ }
+
/*
* Have to precreate these, as they can be referenced by
* earlier instructions.
dname = dname_buf;
values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
+ if (ins->opcode == OP_VPHI)
+ addresses [ins->dreg] = values [ins->dreg];
+
g_ptr_array_add (phi_values, values [ins->dreg]);
/*
break;
}
case OP_PHI:
- case OP_FPHI: {
+ case OP_FPHI:
+ case OP_VPHI: {
int i;
gboolean empty = TRUE;
}
/* Convert the value to the type required by phi nodes */
- if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
- values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
+ if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg]) {
+ if (!values [ins->dreg])
+ /* vtypes */
+ values [ins->dreg] = addresses [ins->dreg];
+ else
+ values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
+ }
/* Add stores for volatile variables */
if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
return 1;
return 0;
}
+
+ struct VTypePhi {
+ public int i;
+ }
+
+ static int vtype_phi (VTypePhi v1, VTypePhi v2, bool first) {
+ VTypePhi v = first ? v1 : v2;
+
+ return v.i;
+ }
+
+ static int test_0_vtype_phi ()
+ {
+ VTypePhi v1 = new VTypePhi () { i = 1 };
+ VTypePhi v2 = new VTypePhi () { i = 2 };
+
+ if (vtype_phi (v1, v2, true) != 1)
+ return 1;
+ if (vtype_phi (v1, v2, false) != 2)
+ return 2;
+
+ return 0;
+ }
}