aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--Documentation/IR.rst10
-rw-r--r--cse.c4
-rw-r--r--example.c2
-rw-r--r--linearize.c7
-rw-r--r--linearize.h1
-rw-r--r--simplify.c1
-rw-r--r--sparse-llvm.c25
-rw-r--r--sparse.c1
-rw-r--r--validation/linear/bool-cast-lp32.c19
-rw-r--r--validation/linear/bool-cast-lp64.c18
-rw-r--r--validation/linear/bool-cast.c1
-rw-r--r--validation/linear/cast-kinds.c8
-rw-r--r--validation/optim/kill-casts.c1
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.
diff --git a/cse.c b/cse.c
index 2a076709..5a55caa7 100644
--- a/cse.c
+++ b/cse.c
@@ -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.
*/
diff --git a/example.c b/example.c
index 2bc9de2c..4ca663e6 100644
--- a/example.c
+++ b/example.c
@@ -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,
diff --git a/simplify.c b/simplify.c
index 274202fa..cf1c8d5f 100644
--- a/simplify.c
+++ b/simplify.c
@@ -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;
diff --git a/sparse.c b/sparse.c
index afdc314e..d4884007 100644
--- a/sparse.c
+++ b/sparse.c
@@ -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\\.
*/