diff options
| -rw-r--r-- | Documentation/IR.rst | 10 | ||||
| -rw-r--r-- | cse.c | 4 | ||||
| -rw-r--r-- | example.c | 2 | ||||
| -rw-r--r-- | linearize.c | 7 | ||||
| -rw-r--r-- | linearize.h | 1 | ||||
| -rw-r--r-- | simplify.c | 1 | ||||
| -rw-r--r-- | sparse-llvm.c | 25 | ||||
| -rw-r--r-- | sparse.c | 1 | ||||
| -rw-r--r-- | validation/linear/bool-cast-lp32.c | 19 | ||||
| -rw-r--r-- | validation/linear/bool-cast-lp64.c | 18 | ||||
| -rw-r--r-- | validation/linear/bool-cast.c | 1 | ||||
| -rw-r--r-- | validation/linear/cast-kinds.c | 8 | ||||
| -rw-r--r-- | validation/optim/kill-casts.c | 1 |
13 files changed, 84 insertions, 14 deletions
diff --git a/Documentation/IR.rst b/Documentation/IR.rst index b7fe98a4..61575386 100644 --- a/Documentation/IR.rst +++ b/Documentation/IR.rst @@ -264,8 +264,11 @@ They all have the following signature: * .target: result value * .type: type of .target +Currently, a cast to a void pointer is treated like a cast to +an unsigned integer of the same size. + .. op:: OP_CAST - Cast to unsigned integer (and to void pointer). + Cast to unsigned integer. .. op:: OP_SCAST Cast to signed integer. @@ -273,8 +276,11 @@ They all have the following signature: .. op:: OP_UTPTR Cast from pointer-sized unsigned integer to pointer type. +.. op:: OP_PTRTU + Cast from pointer type to unsigned integer. + .. op:: OP_PTRCAST - Cast to pointer. + Cast between pointers. .. op:: OP_FCVTU Conversion from float type to unsigned integer. @@ -94,7 +94,7 @@ void cse_collect(struct instruction *insn) case OP_CAST: case OP_SCAST: case OP_PTRCAST: - case OP_UTPTR: + case OP_UTPTR: case OP_PTRTU: /* * This is crap! Many "orig_types" are the * same as far as casts go, we should generate @@ -242,7 +242,7 @@ static int insn_compare(const void *_i1, const void *_i2) case OP_CAST: case OP_SCAST: case OP_PTRCAST: - case OP_UTPTR: + case OP_UTPTR: case OP_PTRTU: /* * This is crap! See the comments on hashing. */ @@ -82,6 +82,7 @@ static const char *opcodes[] = { [OP_SCVTF] = "scvtf", [OP_FCVTF] = "fcvtf", [OP_UTPTR] = "utptr", + [OP_PTRTU] = "utptr", [OP_PTRCAST] = "ptrcast", [OP_CALL] = "call", [OP_SLICE] = "slice", @@ -1416,6 +1417,7 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state) case OP_CAST: case OP_SCAST: case OP_PTRCAST: case OP_UTPTR: + case OP_PTRTU: case OP_FCVTU: case OP_FCVTS: case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: diff --git a/linearize.c b/linearize.c index 01bd68d2..de6e4b93 100644 --- a/linearize.c +++ b/linearize.c @@ -269,6 +269,7 @@ static const char *opcodes[] = { [OP_SCVTF] = "scvtf", [OP_FCVTF] = "fcvtf", [OP_UTPTR] = "utptr", + [OP_PTRTU] = "ptrtu", [OP_PTRCAST] = "ptrcast", [OP_INLINED_CALL] = "# call", [OP_CALL] = "call", @@ -454,6 +455,7 @@ const char *show_instruction(struct instruction *insn) case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: case OP_UTPTR: + case OP_PTRTU: case OP_PTRCAST: buf += sprintf(buf, "%s <- (%d) %s", show_pseudo(insn->target), @@ -1250,6 +1252,11 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src) switch (stype) { case MTYPE_FLOAT: return dtype == MTYPE_UINT ? OP_FCVTU : OP_FCVTS; + case MTYPE_PTR: + return OP_PTRTU; + case MTYPE_VPTR: + case MTYPE_UINT: + return OP_CAST; case MTYPE_SINT: return OP_SCAST; default: diff --git a/linearize.h b/linearize.h index c5d98a2d..d660d332 100644 --- a/linearize.h +++ b/linearize.h @@ -227,6 +227,7 @@ enum opcode { OP_UCVTF, OP_SCVTF, OP_FCVTF, OP_UTPTR, + OP_PTRTU, OP_PTRCAST, OP_UNOP_END = OP_PTRCAST, @@ -1224,6 +1224,7 @@ int simplify_instruction(struct instruction *insn) case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: case OP_UTPTR: + case OP_PTRTU: case OP_PTRCAST: return simplify_cast(insn); case OP_PHI: diff --git a/sparse-llvm.c b/sparse-llvm.c index 8732f989..69b77a37 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -881,17 +881,29 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn) LLVMOpcode op; char target_name[64]; - assert(is_ptr_type(insn->type)); - src = get_operand(fn, otype, insn->src); pseudo_name(insn->target, target_name); dtype = symbol_type(insn->type); - if (is_ptr_type(otype)) { - op = LLVMBitCast; - } else if (is_int_type(otype)) { + switch (insn->opcode) { + case OP_UTPTR: + case OP_SCAST: // FIXME + assert(is_int_type(otype)); + assert(is_ptr_type(insn->type)); op = LLVMIntToPtr; - } else { + break; + case OP_PTRTU: + assert(is_ptr_type(otype)); + assert(is_int_type(insn->type)); + op = LLVMPtrToInt; + break; + case OP_PTRCAST: + case OP_CAST: // FIXME + assert(is_ptr_type(otype)); + assert(is_ptr_type(insn->type)); + op = LLVMBitCast; + break; + default: assert(0); } @@ -1046,6 +1058,7 @@ static void output_insn(struct function *fn, struct instruction *insn) output_op_fpcast(fn, insn); break; case OP_UTPTR: + case OP_PTRTU: case OP_PTRCAST: output_op_ptrcast(fn, insn); break; @@ -217,6 +217,7 @@ static void check_one_instruction(struct instruction *insn) { switch (insn->opcode) { case OP_CAST: case OP_SCAST: + case OP_PTRTU: if (verbose) check_cast_instruction(insn); break; diff --git a/validation/linear/bool-cast-lp32.c b/validation/linear/bool-cast-lp32.c new file mode 100644 index 00000000..44a650f4 --- /dev/null +++ b/validation/linear/bool-cast-lp32.c @@ -0,0 +1,19 @@ +extern int ffun(void); +typedef void *vdp; +typedef int *sip; + +static _Bool fvdp_i(vdp a) { return a; } +static _Bool fvdp_e(vdp a) { return (_Bool)a; } +static _Bool fsip_i(sip a) { return a; } +static _Bool fsip_e(sip a) { return (_Bool)a; } +static _Bool ffun_i(void) { return ffun; } +static _Bool ffun_e(void) { return (_Bool)ffun; } + +/* + * check-name: bool-cast-pointer + * check-command: test-linearize -m32 -fdump-ir $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: ptrtu\\. + */ diff --git a/validation/linear/bool-cast-lp64.c b/validation/linear/bool-cast-lp64.c new file mode 100644 index 00000000..9b2a020a --- /dev/null +++ b/validation/linear/bool-cast-lp64.c @@ -0,0 +1,18 @@ +extern int ffun(void); +typedef void *vdp; +typedef int *sip; + +static _Bool fvdp_i(vdp a) { return a; } +static _Bool fvdp_e(vdp a) { return (_Bool)a; } +static _Bool fsip_i(sip a) { return a; } +static _Bool fsip_e(sip a) { return (_Bool)a; } +static _Bool ffun_i(void) { return ffun; } +static _Bool ffun_e(void) { return (_Bool)ffun; } + +/* + * check-name: bool-cast-pointer + * check-command: test-linearize -m64 -fdump-ir $file + * + * check-output-ignore + * check-output-excludes: ptrtu\\. + */ diff --git a/validation/linear/bool-cast.c b/validation/linear/bool-cast.c index 094f4438..43276a46 100644 --- a/validation/linear/bool-cast.c +++ b/validation/linear/bool-cast.c @@ -28,6 +28,7 @@ static _Bool fdbl_e(dbl a) { return (_Bool)a; } * check-output-ignore * check-output-excludes: cast\\. * check-output-excludes: fcvt[us]\\. + * check-output-excludes: ptrtu\\. * check-output-pattern(12): setne\\. * check-output-pattern(2): fcmpune\\. */ diff --git a/validation/linear/cast-kinds.c b/validation/linear/cast-kinds.c index 1742cd1e..6683ea93 100644 --- a/validation/linear/cast-kinds.c +++ b/validation/linear/cast-kinds.c @@ -88,7 +88,7 @@ vptr_2_int: iptr_2_int: .L8: <entry-point> - cast.32 %r14 <- (64) %arg1 + ptrtu.32 %r14 <- (64) %arg1 ret.32 %r14 @@ -136,7 +136,7 @@ vptr_2_uint: iptr_2_uint: .L22: <entry-point> - cast.32 %r35 <- (64) %arg1 + ptrtu.32 %r35 <- (64) %arg1 ret.32 %r35 @@ -184,7 +184,7 @@ vptr_2_long: iptr_2_long: .L36: <entry-point> - cast.64 %r56 <- (64) %arg1 + ptrtu.64 %r56 <- (64) %arg1 ret.64 %r56 @@ -232,7 +232,7 @@ vptr_2_ulong: iptr_2_ulong: .L50: <entry-point> - cast.64 %r77 <- (64) %arg1 + ptrtu.64 %r77 <- (64) %arg1 ret.64 %r77 diff --git a/validation/optim/kill-casts.c b/validation/optim/kill-casts.c index c375f5fb..140b8d20 100644 --- a/validation/optim/kill-casts.c +++ b/validation/optim/kill-casts.c @@ -21,4 +21,5 @@ void foo(struct s *x) * check-output-excludes: cast\\. * check-output-excludes: fcvt[us]\\. * check-output-excludes: utptr\\. + * check-output-excludes: ptrtu\\. */ |
