* [RFC PATCH 00/14] rework of cast operations
@ 2017-08-17 4:05 Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 01/14] add documentation for IR instructions Luc Van Oostenryck
` (13 more replies)
0 siblings, 14 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
The goal of this series is to specialize the few cast
instuctions into more specialized ones so that the
precise nature of the operations is fully specified
by the instruction and thus no additional need to be
done later.
With this series we have:
- TRUNC, for int to smaller size int
- ZEXT, for int to bigger int with zero extend
- SEXT, for int to bigger int with sign extend
- PTRTU, for pointer to same sized [unsigned] int
- UTPTR, for pointer from same sized [unsigned] int
- PTRCAST, for pointer to pointer
- FCVT[US], for float to unsigned/signed integer
- [US]CVTF, for float from unsigned/signed integer
- FCVTF, for float to float
Also:
- for these casts, void pointer are treated as unsigned integers
- casts from int to same sized int are trated as NOP and never
generated.
There are few points I'm not yet decided about, especially thinking
about what would be needed to to [type based] analysis:
- maybe we should no drop the NOP and have a real NOPCAST ?
- this NOPCAST may then be used for floats and pointers too?
- this NOPCAST could then be simplified away when needed
- PTRTU & UTPTR are in the same situation:
- are they needed?
- when can we simplified them away?
- it may be good to split FCVTF into: FTRUNC, NOPCAST & TEXT
- is it still good to treat void pointers the same as some integer?
----------------------------------------------------------------
This series is also available in the git repository at:
git://github.com/lucvoo/sparse.git cast-rework
----------------------------------------------------------------
Luc Van Oostenryck (14):
add documentation for IR instructions
cast: add tests for warnings issued by sparse -v
cast: prepare finer grained cast instructions
cast: specialize FPCAST into [USF]CVTF
cast: handle NO-OP casts
cast: specialize floats to integer conversion
cast: specialize casts from unsigned to pointers
cast: make [u]intptr_ctype alias of [s]size_t_ctype
cast: make pointer casts always size preserving
cast: temporary simplify handling cast to/from void*
cast: specialize cast from pointers
cast: add support for -Wpointer-to-int-cast
cast: make casts from pointer always size preserving
cast: specialize integer casts
Documentation/IR.md | 330 +++++++++++++++++++++++++++++++++
cse.c | 10 +-
example.c | 22 ++-
lib.c | 4 +
lib.h | 2 +
linearize.c | 165 ++++++++++++++---
linearize.h | 11 +-
liveness.c | 10 +-
simplify.c | 54 +++---
sparse-llvm.c | 21 ++-
sparse.c | 5 +-
symbol.h | 3 +
validation/bitfield-size.c | 5 +-
validation/builtin-bswap-variable.c | 4 +-
validation/cast-kinds-check.c | 19 ++
validation/cast-kinds.c | 181 ++++++++++--------
validation/cast-weirds.c | 51 +++++
validation/compound-assign-type.c | 3 +-
validation/linear/bitfield-init-zero.c | 8 +-
validation/memops-volatile.c | 4 +-
validation/optim/bool-simplify.c | 4 +-
21 files changed, 757 insertions(+), 159 deletions(-)
create mode 100644 Documentation/IR.md
create mode 100644 validation/cast-kinds-check.c
create mode 100644 validation/cast-weirds.c
^ permalink raw reply [flat|nested] 16+ messages in thread
* [RFC PATCH 01/14] add documentation for IR instructions
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-21 12:18 ` Christopher Li
2017-08-17 4:05 ` [RFC PATCH 02/14] cast: add tests for warnings issued by sparse -v Luc Van Oostenryck
` (12 subsequent siblings)
13 siblings, 1 reply; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Until now the 'instructions' used for spare's IR are
not at all documented.
This patch is a fist step toward having these instructions
properly documented.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 306 insertions(+)
create mode 100644 Documentation/IR.md
diff --git a/Documentation/IR.md b/Documentation/IR.md
new file mode 100644
index 000000000..7e13e740d
--- /dev/null
+++ b/Documentation/IR.md
@@ -0,0 +1,306 @@
+# Sparse Instructions (IR)
+
+## General
+Sparse's instructions clearly belong to the family of
+3-addresses code: most instruction taking one or two
+operands and produce one result.
+
+Concretely, things are a bit more complex as a few instructions
+take 3 operands and some take an unbounded number of operands.
+The type of each of these operands can also differs.
+
+Operands, result and some parameters are stored in the members
+of a `struct instruction`.
+Some of these members are used by almost all instructions,
+some others are specific to only one or a few instructions.
+The common ones are:
+- `.src1`, `.src2`, `.src3`: operands of binops or ternary ops, type is `pseudo_t`.
+- `.src`: operand of unary ops (alias for `.src1`), type is `pseudo_t`.
+- `.target`: result of unary, binary & ternary ops, is sometimes used
+ otherwise by some others instructions, type is `pseudo_t`.
+- `.cond`: input operands for condition (alias `.target`!), type is `pseudo_t`.
+- `.type`: usually the type of `.result`, sometimes of the operands, type is `struct symbol *`.
+
+## Terminators
+### OP_RET
+Return from subroutine.
+- `.src` : returned value (NULL if void)
+- `.type`: type of `.src`
+
+### OP_BR
+Unconditional branch
+- `.bb_true`: destination basic block
+
+### OP_CBR
+Conditional branch
+- `.cond`: condition
+- `.type`: type of `.cond`, must be an integral type
+- `.bb_true`, `.bb_false`: destination basic blocks
+
+### OP_SWITCH
+Switch / multi-branch
+- `.cond`: condition
+- `.type`: type of `.cond`, must be an integral type
+- `.multijmp_list`: pairs of case-value - destination basic block
+
+### OP_COMPUTEDGOTO
+Computed goto / branch to register
+- `.target`: target address (type is irrelevant, void*)
+- `.multijmp_list`: list of possible destination basic blocks
+
+## Arithmetic binops
+They all follow the same signature:
+- `.src1`, `.src2`: operands (types must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`
+
+### OP_ADD
+Addition.
+
+### OP_SUB
+Subtraction.
+
+### OP_MULU
+Multiplication (unsigned ints & floating-points)
+
+### OP_MULS
+Multiplication (signed ints)
+
+### OP_DIVU
+Division (unsigned ints & floating-points)
+
+### OP_DIVS
+Division (signed ints)
+
+### OP_MODU
+Modulo (unsigned division remainder, integer only)
+
+### OP_MODS
+Modulo (signed division remainder, integer only)
+
+### OP_SHL
+Shift left (integer only)
+
+### OP_LSR
+Logical Shift right (integer only)
+
+### OP_ASR
+Arithmetic Shift right (integer only)
+
+## Logical ops
+They all follow the same signature:
+- `.src1`, `.src2`: operands (types must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`, must be an integral type
+
+### OP_AND
+### OP_OR
+### OP_XOR
+
+## Boolean ops
+### OP_AND_BOOL
+### OP_OR_BOOL
+
+## Comparisons
+They all have the following signature:
+- `.src1`, `.src2`: operands (types must be compatible)
+- `.target`: result of the operation (0/1 valued integer)
+- `.type`: type of `.target`, must be an integral type
+
+### OP_SET_EQ
+Compare equal.
+
+### OP_SET_NE
+Compare not-equal.
+
+### OP_SET_LE
+Compare less-than-or-equal (signed).
+
+### OP_SET_GE
+Compare greater-than-or-equal (signed).
+
+### OP_SET_LT
+Compare less-than (signed).
+
+### OP_SET_GT
+Compare greater-than (signed).
+
+### OP_SET_B
+Compare less-than (unsigned).
+
+### OP_SET_A
+Compare greater-than (unsigned).
+
+### OP_SET_BE
+Compare less-than-or-equal (unsigned).
+
+### OP_SET_AE
+Compare greater-than-or-equal (unsigned).
+
+## Unary ops
+### OP_NOT
+Logical not.
+- `.src`: operand (type must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`, must be an integral type
+
+### OP_NEG
+Arithmetic negation.
+- `.src`: operand (type must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`
+
+## Type conversions
+They all have the following signature:
+- `.src`: source value
+- `.orig_type`: type of `.src`
+- `.target`: result value
+- `.type`: type of `.target`
+
+### OP_CAST
+Cast to unsigned integer (and to void pointer).
+
+### OP_SCAST
+Cast to signed integer.
+
+### OP_FPCAST
+Cast to floating-point.
+
+### OP_PTRCAST
+Cast to pointer.
+
+## Ternary ops
+### OP_SEL
+- `.src1`: condition, must be of integral type
+- `.src2`, `.src3`: operands (types must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`
+
+## Memory ops
+### OP_LOAD
+Load.
+- `.src`: base address to load from
+- `.offset`: address offset
+- `.target`: loaded value
+- `.type`: type of `.target`
+
+### OP_STORE
+Store.
+- `.src`: base address to store to
+- `.offset`: address offset
+- `.target`: value to be stored
+- `.type`: type of `.target`
+
+## Others
+### OP_SYMADDR
+Create a pseudo corresponding to the address of a symbol.
+- `.symbol`: input symbol (alias `.src`), type is `pseudo_t`
+- `.target`: symbol's address
+
+### OP_SETVAL
+Create a pseudo corresponding to a value.
+The value is given as an expression EXPR_STRING, EXPR_FVALUE or
+EXPR_LABEL (pseudos for integral constants are directly created
+at linearization and doesn't need this instruction)
+- `.val`: (expression) input expression
+- `.target`: the resulting value
+- `.type`: type of `.target`, the value
+
+### OP_PHI
+Phi-node (for SSA form).
+- `.phi_list`: phi-operands (type must be compatible with `.target`)
+- `.target`: "result"
+- `.type`: type of `.target`
+
+### OP_PHISOURCE
+Phi-node source.
+Like OP_COPY but exclusively used to give a defining instructions
+(and thus also a type) to *all* OP_PHI operands.
+- `.phi_src`: operand (type must be compatible with `.target`, alias `.src`)
+- `.target`: the "result" PSEUDO_PHI
+- `.type`: type of `.target`
+- `.phi_users`: list of phi instructions using the target pseudo
+
+### OP_PUSH
+Give an argument to the following OP_CALL.
+- `.arg`: argument (alias `.src`), type is `pseudo_t`
+- `.type`: type of `.src`
+- `.call`: corresponding instruction
+
+### OP_CALL
+Function call.
+- `.func`: the function (can be a symbol or a "register", alias `.src`)), type is `pseudo_t`
+- `.arguments`: list of the associated OP_PUSH instructions
+- `.target`: function return value (if any)
+- `.type`: type of `.target`
+- `.fntype`: the full function type
+
+### OP_INLINED_CALL
+Only used as an annotation to show that the instructions just above
+correspond to a function that have been inlined.
+- `.func`: the function (must be a symbol, alias `.src`)), type is `pseudo_t`
+- `.inlined_args`: list of pseudos that where the function's arguments
+- `.target`: function return value (if any)
+- `.type`: type of `.target`
+- `.fntype`: the full function type
+
+### OP_SLICE
+Extract a "slice" from an aggregate.
+- `.base`: aggregate (alias `.src`), type is `pseudo_t`
+- `.from`, `.len`: offet & size of the "slice" within the aggregate
+- `.target`: result
+- `.type`: type of `.target`
+
+### OP_ASM
+Inlined assembly code.
+- `.string`: asm template
+- `.asm_rules`: asm constraints, rules
+
+## Sparse tagging (line numbers, context, whatever)
+### OP_CONTEXT
+Currently only used for lock/unlock tracking.
+- `.context_expr`: unused
+- `.increment`: (1 for locking, -1 for unlocking)
+- `.check`: (ignore the instruction if 0)
+
+## Misc ops
+### OP_ENTRY
+Function entry point (no associated semantic).
+
+### OP_BADOP
+Invalid operation (should never be generated).
+
+### OP_NOP
+No-op (should never be generated).
+
+### OP_SNOP
+Store no-op (removed store operation).
+
+### OP_LNOP
+Load no-op (removed load operation).
+
+### OP_DEATHNOTE
+Annotation telling the pseudo will be death after the next
+instruction (other than some other annotation, that is).
+
+### OP_COPY
+Copy (only needed after out-of-SSA).
+- `.src`: operand (type must be compatible with `.target`)
+- `.target`: result of the operation
+- `.type`: type of `.target`
+
+### OP_RANGE
+Range/bounds checking (only used for an unused sparse extension).
+- `.src1`: value to be checked
+- `.src2`, src3: bound of the value (must be constants?)
+- `.type`: type of `.src`
+
+## Unused ops
+### OP_VANEXT
+### OP_VAARG
+### OP_MALLOC
+### OP_FREE
+### OP_ALLOCA
+### OP_GET_ELEMENT_PTR
+### OP_INVOKE
+### OP_UNWIND
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 02/14] cast: add tests for warnings issued by sparse -v
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 01/14] add documentation for IR instructions Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 03/14] cast: prepare finer grained cast instructions Luc Van Oostenryck
` (11 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
The sparse command (aka the 'checker') do a number of additional
checks when used with the -v flag. I strongly believes that this
option is rarely used let me not disgress about it here.
One of this additional checks are about casts.
Let add soe testcase in thr tessuite in order to avoid any
regression there.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
validation/cast-kinds-check.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 validation/cast-kinds-check.c
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
new file mode 100644
index 000000000..f3ece313a
--- /dev/null
+++ b/validation/cast-kinds-check.c
@@ -0,0 +1,26 @@
+#include "cast-kinds.c"
+
+/*
+ * check-name: cast-kinds check
+ * check-command: sparse -m64 -v $file
+ *
+ * check-error-start
+cast-kinds.c:5:45: warning: cast drops bits
+cast-kinds.c:6:47: warning: cast drops bits
+cast-kinds.c:7:46: warning: cast drops bits
+cast-kinds.c:8:45: warning: cast drops bits
+cast-kinds.c:10:49: warning: cast drops bits
+cast-kinds.c:12:48: warning: cast drops bits
+cast-kinds.c:13:50: warning: cast drops bits
+cast-kinds.c:14:49: warning: cast drops bits
+cast-kinds.c:15:48: warning: cast drops bits
+cast-kinds.c:17:52: warning: cast drops bits
+cast-kinds.c:21:49: warning: cast wasn't removed
+cast-kinds.c:22:48: warning: cast wasn't removed
+cast-kinds.c:28:52: warning: cast wasn't removed
+cast-kinds.c:29:51: warning: cast wasn't removed
+cast-kinds.c:34:52: warning: cast wasn't removed
+cast-kinds.c:35:54: warning: cast wasn't removed
+cast-kinds.c:36:52: warning: cast wasn't removed
+ * check-error-end
+ */
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 03/14] cast: prepare finer grained cast instructions
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 01/14] add documentation for IR instructions Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 02/14] cast: add tests for warnings issued by sparse -v Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 04/14] cast: specialize FPCAST into [USF]CVTF Luc Van Oostenryck
` (10 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
As a first step, add a small function classify values into
'machine type:
- signed integer
- unsigned integer
- pointer
- floats
and use this to select the appropriate O_XXXCAST.
Note: this is a preparatory patch and should not introduce
any changes in the generated IR.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
linearize.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 63 insertions(+), 15 deletions(-)
diff --git a/linearize.c b/linearize.c
index ba76397ea..c77a3c2df 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1109,28 +1109,75 @@ static pseudo_t linearize_postop(struct entrypoint *ep, struct expression *expr)
* case, since you can't access through it anyway without another
* cast.
*/
-static struct instruction *alloc_cast_instruction(struct symbol *src, struct symbol *ctype)
+enum mtype {
+ MTYPE_UINT,
+ MTYPE_SINT,
+ MTYPE_PTR,
+ MTYPE_FLOAT,
+ MTYPE_BAD,
+};
+
+static enum mtype get_mtype(struct symbol *s)
+{
+ int sign = (s->ctype.modifiers & MOD_SIGNED) ? 1 : 0;
+
+retry: switch (s->type) {
+ case SYM_NODE:
+ s = s->ctype.base_type;
+ goto retry;
+ case SYM_PTR:
+ if (s->ctype.base_type == &void_ctype)
+ // handle void pointer like an uint
+ goto case_int;
+ return MTYPE_PTR;
+ case SYM_BITFIELD:
+ case SYM_RESTRICT:
+ case SYM_FOULED:
+ case SYM_ENUM:
+ s = s->ctype.base_type;
+ /* fall-through */
+ case_int:
+ return sign ? MTYPE_SINT : MTYPE_UINT;
+ case SYM_BASETYPE:
+ if (s->ctype.base_type == &fp_type)
+ return MTYPE_FLOAT;
+ if (s->ctype.base_type == &int_type)
+ goto case_int;
+ /* fall-through */
+ default:
+ return MTYPE_BAD;
+ }
+}
+
+static int get_cast_opcode(struct symbol *dst, struct symbol *src)
{
- int opcode = OP_CAST;
- struct symbol *base = ctype;
+ enum mtype stype = get_mtype(src);
+ enum mtype dtype = get_mtype(dst);
- if (src->ctype.modifiers & MOD_SIGNED)
- opcode = OP_SCAST;
- if (base->type == SYM_NODE)
- base = base->ctype.base_type;
- if (base->type == SYM_PTR) {
- base = base->ctype.base_type;
- if (base != &void_ctype)
- opcode = OP_PTRCAST;
- } else if (base->ctype.base_type == &fp_type)
- opcode = OP_FPCAST;
- return alloc_typed_instruction(opcode, ctype);
+ switch (dtype) {
+ case MTYPE_FLOAT:
+ return OP_FPCAST;
+ case MTYPE_PTR:
+ return OP_PTRCAST;
+ case MTYPE_UINT:
+ case MTYPE_SINT:
+ switch (stype) {
+ case MTYPE_SINT:
+ return OP_SCAST;
+ default:
+ break;
+ }
+ /* fall through */
+ default:
+ return OP_CAST;
+ }
}
static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *from, struct symbol *to)
{
pseudo_t result;
struct instruction *insn;
+ int opcode;
if (src == VOID)
return VOID;
@@ -1138,7 +1185,8 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
return VOID;
if (from->bit_size < 0 || to->bit_size < 0)
return VOID;
- insn = alloc_cast_instruction(from, to);
+ opcode = get_cast_opcode(to, from);
+ insn = alloc_typed_instruction(opcode, to);
result = alloc_pseudo(insn);
insn->target = result;
insn->orig_type = from;
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 04/14] cast: specialize FPCAST into [USF]CVTF
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (2 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 03/14] cast: prepare finer grained cast instructions Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 05/14] cast: handle NO-OP casts Luc Van Oostenryck
` (9 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently, all cast to a floating point type use OP_FPCAST.
This is aybe simple but rather uncovenient as it correspond
to several quite different operation that later need extra
checks.
Change this by directly using different instructions for the
different case:
- FCVTF for float-float conversions
- UCVTF for unsigned integer to floats
- SCVTF for signed integer to floats
and reject attempts to cast a pointer to a float.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 12 +++++++++---
example.c | 8 ++++++--
linearize.c | 18 +++++++++++++++---
linearize.h | 3 ++-
liveness.c | 3 ++-
simplify.c | 11 +++++++----
sparse-llvm.c | 3 ++-
validation/cast-kinds.c | 20 ++++++++++----------
8 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index 7e13e740d..2d23e65d3 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -163,12 +163,18 @@ Cast to unsigned integer (and to void pointer).
### OP_SCAST
Cast to signed integer.
-### OP_FPCAST
-Cast to floating-point.
-
### OP_PTRCAST
Cast to pointer.
+### OP_UCVTF
+Conversion from unsigned integer to a float type.
+
+### OP_SCVTF
+Conversion from signed integer to a float type.
+
+### OP_FCVTF
+Conversion between float types.
+
## Ternary ops
### OP_SEL
- `.src1`: condition, must be of integral type
diff --git a/example.c b/example.c
index 691e0f97c..30e91bbf6 100644
--- a/example.c
+++ b/example.c
@@ -83,7 +83,9 @@ static const char *opcodes[] = {
[OP_COPY] = "copy",
[OP_CAST] = "cast",
[OP_SCAST] = "scast",
- [OP_FPCAST] = "fpcast",
+ [OP_UCVTF] = "ucvtf",
+ [OP_SCVTF] = "scvtf",
+ [OP_FCVTF] = "fcvtf",
[OP_PTRCAST] = "ptrcast",
[OP_CALL] = "call",
[OP_VANEXT] = "va_next",
@@ -1420,7 +1422,9 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
generate_compare(state, insn);
break;
- case OP_CAST: case OP_SCAST: case OP_FPCAST: case OP_PTRCAST:
+ case OP_CAST: case OP_SCAST: case OP_PTRCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
generate_cast(state, insn);
break;
diff --git a/linearize.c b/linearize.c
index c77a3c2df..7f8dbc64a 100644
--- a/linearize.c
+++ b/linearize.c
@@ -230,7 +230,9 @@ static const char *opcodes[] = {
[OP_PHISOURCE] = "phisrc",
[OP_CAST] = "cast",
[OP_SCAST] = "scast",
- [OP_FPCAST] = "fpcast",
+ [OP_UCVTF] = "ucvtf",
+ [OP_SCVTF] = "scvtf",
+ [OP_FCVTF] = "fcvtf",
[OP_PTRCAST] = "ptrcast",
[OP_INLINED_CALL] = "# call",
[OP_CALL] = "call",
@@ -425,7 +427,8 @@ const char *show_instruction(struct instruction *insn)
}
case OP_CAST:
case OP_SCAST:
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
case OP_PTRCAST:
buf += sprintf(buf, "%s <- (%d) %s",
show_pseudo(insn->target),
@@ -1156,7 +1159,16 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
switch (dtype) {
case MTYPE_FLOAT:
- return OP_FPCAST;
+ switch (stype) {
+ case MTYPE_FLOAT:
+ return OP_FCVTF;
+ case MTYPE_UINT:
+ return OP_UCVTF;
+ case MTYPE_SINT:
+ return OP_SCVTF;
+ default:
+ return OP_BADOP;
+ }
case MTYPE_PTR:
return OP_PTRCAST;
case MTYPE_UINT:
diff --git a/linearize.h b/linearize.h
index bac82d7ff..0ec42e588 100644
--- a/linearize.h
+++ b/linearize.h
@@ -198,7 +198,8 @@ enum opcode {
OP_PHISOURCE,
OP_CAST,
OP_SCAST,
- OP_FPCAST,
+ OP_UCVTF, OP_SCVTF,
+ OP_FCVTF,
OP_PTRCAST,
OP_INLINED_CALL,
OP_CALL,
diff --git a/liveness.c b/liveness.c
index 7461738b4..b3e0a8326 100644
--- a/liveness.c
+++ b/liveness.c
@@ -113,7 +113,8 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
case OP_CAST:
case OP_SCAST:
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
case OP_PTRCAST:
USES(src); DEFINES(target);
break;
diff --git a/simplify.c b/simplify.c
index 2bc86f53e..e0f31ad45 100644
--- a/simplify.c
+++ b/simplify.c
@@ -238,7 +238,8 @@ void kill_insn(struct instruction *insn, int force)
case OP_CAST:
case OP_SCAST:
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
case OP_PTRCAST:
case OP_SETVAL:
case OP_NOT: case OP_NEG:
@@ -340,7 +341,8 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo)
case OP_SYMADDR:
case OP_CAST:
case OP_SCAST:
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
case OP_PTRCAST:
kill_use(&insn->src1);
break;
@@ -973,7 +975,7 @@ static int simplify_cast(struct instruction *insn)
int op = (orig_type->ctype.modifiers & MOD_SIGNED) ? OP_SCAST : OP_CAST;
if (insn->opcode == op)
goto simplify;
- if (insn->opcode == OP_FPCAST && is_float_type(orig_type))
+ if (insn->opcode == OP_FCVTF)
goto simplify;
}
@@ -1201,7 +1203,8 @@ int simplify_instruction(struct instruction *insn)
return replace_with_pseudo(insn, insn->symbol);
case OP_CAST:
case OP_SCAST:
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
case OP_PTRCAST:
return simplify_cast(insn);
case OP_PHI:
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 29fb65f15..c45729ef4 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -855,7 +855,8 @@ static void output_insn(struct function *fn, struct instruction *insn)
case OP_SCAST:
output_op_cast(fn, insn, LLVMSExt);
break;
- case OP_FPCAST:
+ case OP_UCVTF: case OP_SCVTF:
+ case OP_FCVTF:
assert(0);
break;
case OP_PTRCAST:
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index 697f9735e..34bf685d2 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -316,70 +316,70 @@ vptr_2_iptr:
int_2_float:
.L76:
<entry-point>
- fpcast.32 %r116 <- (32) %arg1
+ scvtf.32 %r116 <- (32) %arg1
ret.32 %r116
uint_2_float:
.L78:
<entry-point>
- fpcast.32 %r119 <- (32) %arg1
+ ucvtf.32 %r119 <- (32) %arg1
ret.32 %r119
long_2_float:
.L80:
<entry-point>
- fpcast.32 %r122 <- (64) %arg1
+ scvtf.32 %r122 <- (64) %arg1
ret.32 %r122
ulong_2_float:
.L82:
<entry-point>
- fpcast.32 %r125 <- (64) %arg1
+ ucvtf.32 %r125 <- (64) %arg1
ret.32 %r125
double_2_float:
.L84:
<entry-point>
- fpcast.32 %r128 <- (64) %arg1
+ fcvtf.32 %r128 <- (64) %arg1
ret.32 %r128
int_2_double:
.L86:
<entry-point>
- fpcast.64 %r131 <- (32) %arg1
+ scvtf.64 %r131 <- (32) %arg1
ret.64 %r131
uint_2_double:
.L88:
<entry-point>
- fpcast.64 %r134 <- (32) %arg1
+ ucvtf.64 %r134 <- (32) %arg1
ret.64 %r134
long_2_double:
.L90:
<entry-point>
- fpcast.64 %r137 <- (64) %arg1
+ scvtf.64 %r137 <- (64) %arg1
ret.64 %r137
ulong_2_double:
.L92:
<entry-point>
- fpcast.64 %r140 <- (64) %arg1
+ ucvtf.64 %r140 <- (64) %arg1
ret.64 %r140
float_2_double:
.L94:
<entry-point>
- fpcast.64 %r143 <- (32) %arg1
+ fcvtf.64 %r143 <- (32) %arg1
ret.64 %r143
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 05/14] cast: handle NO-OP casts
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (3 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 04/14] cast: specialize FPCAST into [USF]CVTF Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 06/14] cast: specialize floats to integer conversion Luc Van Oostenryck
` (8 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Some casts, the ones which deosn't chnage the size or the resulting
'machine type', are no-op.
Directly simplify away such casts.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
linearize.c | 8 ++++++++
validation/cast-kinds.c | 15 +++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/linearize.c b/linearize.c
index 7f8dbc64a..3f8d955c5 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1161,6 +1161,8 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
case MTYPE_FLOAT:
switch (stype) {
case MTYPE_FLOAT:
+ if (dst->bit_size == src->bit_size)
+ return OP_NOP;
return OP_FCVTF;
case MTYPE_UINT:
return OP_UCVTF;
@@ -1198,6 +1200,12 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
if (from->bit_size < 0 || to->bit_size < 0)
return VOID;
opcode = get_cast_opcode(to, from);
+ switch (opcode) {
+ case OP_NOP:
+ return src;
+ default:
+ break;
+ }
insn = alloc_typed_instruction(opcode, to);
result = alloc_pseudo(insn);
insn->target = result;
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index 34bf685d2..0312bc92b 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -50,6 +50,9 @@ static double long_2_double(long a) { return (double)a; }
static double ulong_2_double(ulong a) { return (double)a; }
static double float_2_double(float a) { return (double)a; }
+static float float_2_float(float a) { return a; }
+static double double_2_double(double a) { return a; }
+
/*
* check-name: cast-kinds
* check-command: test-linearize -m64 $file
@@ -383,5 +386,17 @@ float_2_double:
ret.64 %r143
+float_2_float:
+.L96:
+ <entry-point>
+ ret.32 %arg1
+
+
+double_2_double:
+.L98:
+ <entry-point>
+ ret.64 %arg1
+
+
* check-output-end
*/
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 06/14] cast: specialize floats to integer conversion
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (4 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 05/14] cast: handle NO-OP casts Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 07/14] cast: specialize casts from unsigned to pointers Luc Van Oostenryck
` (7 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently, casts from floats to integers are processed like
integers (or any other type) to integers. This is simple but
rather uncovenient as it correspond to different operations
tat may obey to different rules and which later need extra checks.
Change this by directly using specific instructions:
- FCVTU for floats to unsigned integer
- FCVTS for floats to signed integer
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 6 ++++++
example.c | 3 +++
linearize.c | 5 +++++
linearize.h | 1 +
liveness.c | 1 +
simplify.c | 3 +++
sparse-llvm.c | 1 +
validation/cast-kinds-check.c | 2 --
validation/cast-kinds.c | 20 ++++++++++++--------
9 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index 2d23e65d3..0bfd9765c 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -166,6 +166,12 @@ Cast to signed integer.
### OP_PTRCAST
Cast to pointer.
+### OP_FCVTU
+Conversion from float type to unsigned integer.
+
+### OP_FCVTS
+Conversion from float type to signed integer.
+
### OP_UCVTF
Conversion from unsigned integer to a float type.
diff --git a/example.c b/example.c
index 30e91bbf6..0349a7e20 100644
--- a/example.c
+++ b/example.c
@@ -83,6 +83,8 @@ static const char *opcodes[] = {
[OP_COPY] = "copy",
[OP_CAST] = "cast",
[OP_SCAST] = "scast",
+ [OP_FCVTU] = "fcvtu",
+ [OP_FCVTS] = "fcvts",
[OP_UCVTF] = "ucvtf",
[OP_SCVTF] = "scvtf",
[OP_FCVTF] = "fcvtf",
@@ -1423,6 +1425,7 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
break;
case OP_CAST: case OP_SCAST: case OP_PTRCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
generate_cast(state, insn);
diff --git a/linearize.c b/linearize.c
index 3f8d955c5..75b200c4b 100644
--- a/linearize.c
+++ b/linearize.c
@@ -230,6 +230,8 @@ static const char *opcodes[] = {
[OP_PHISOURCE] = "phisrc",
[OP_CAST] = "cast",
[OP_SCAST] = "scast",
+ [OP_FCVTU] = "fcvtu",
+ [OP_FCVTS] = "fcvts",
[OP_UCVTF] = "ucvtf",
[OP_SCVTF] = "scvtf",
[OP_FCVTF] = "fcvtf",
@@ -427,6 +429,7 @@ const char *show_instruction(struct instruction *insn)
}
case OP_CAST:
case OP_SCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
@@ -1176,6 +1179,8 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
case MTYPE_UINT:
case MTYPE_SINT:
switch (stype) {
+ case MTYPE_FLOAT:
+ return dtype == MTYPE_UINT ? OP_FCVTU : OP_FCVTS;
case MTYPE_SINT:
return OP_SCAST;
default:
diff --git a/linearize.h b/linearize.h
index 0ec42e588..600bae598 100644
--- a/linearize.h
+++ b/linearize.h
@@ -198,6 +198,7 @@ enum opcode {
OP_PHISOURCE,
OP_CAST,
OP_SCAST,
+ OP_FCVTU, OP_FCVTS,
OP_UCVTF, OP_SCVTF,
OP_FCVTF,
OP_PTRCAST,
diff --git a/liveness.c b/liveness.c
index b3e0a8326..3bd95fe5b 100644
--- a/liveness.c
+++ b/liveness.c
@@ -113,6 +113,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
case OP_CAST:
case OP_SCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
diff --git a/simplify.c b/simplify.c
index e0f31ad45..365811b96 100644
--- a/simplify.c
+++ b/simplify.c
@@ -238,6 +238,7 @@ void kill_insn(struct instruction *insn, int force)
case OP_CAST:
case OP_SCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
@@ -341,6 +342,7 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo)
case OP_SYMADDR:
case OP_CAST:
case OP_SCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
@@ -1203,6 +1205,7 @@ int simplify_instruction(struct instruction *insn)
return replace_with_pseudo(insn, insn->symbol);
case OP_CAST:
case OP_SCAST:
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
diff --git a/sparse-llvm.c b/sparse-llvm.c
index c45729ef4..04efc6637 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -855,6 +855,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
case OP_SCAST:
output_op_cast(fn, insn, LLVMSExt);
break;
+ case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
assert(0);
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index f3ece313a..be6b684b4 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -9,12 +9,10 @@ cast-kinds.c:5:45: warning: cast drops bits
cast-kinds.c:6:47: warning: cast drops bits
cast-kinds.c:7:46: warning: cast drops bits
cast-kinds.c:8:45: warning: cast drops bits
-cast-kinds.c:10:49: warning: cast drops bits
cast-kinds.c:12:48: warning: cast drops bits
cast-kinds.c:13:50: warning: cast drops bits
cast-kinds.c:14:49: warning: cast drops bits
cast-kinds.c:15:48: warning: cast drops bits
-cast-kinds.c:17:52: warning: cast drops bits
cast-kinds.c:21:49: warning: cast wasn't removed
cast-kinds.c:22:48: warning: cast wasn't removed
cast-kinds.c:28:52: warning: cast wasn't removed
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index 0312bc92b..d07a94190 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -95,13 +95,14 @@ iptr_2_int:
float_2_int:
.L10:
<entry-point>
- ret.32 %arg1
+ fcvts.32 %r17 <- (32) %arg1
+ ret.32 %r17
double_2_int:
.L12:
<entry-point>
- cast.32 %r20 <- (64) %arg1
+ fcvts.32 %r20 <- (64) %arg1
ret.32 %r20
@@ -142,13 +143,14 @@ iptr_2_uint:
float_2_uint:
.L24:
<entry-point>
- ret.32 %arg1
+ fcvtu.32 %r38 <- (32) %arg1
+ ret.32 %r38
double_2_uint:
.L26:
<entry-point>
- cast.32 %r41 <- (64) %arg1
+ fcvtu.32 %r41 <- (64) %arg1
ret.32 %r41
@@ -189,14 +191,15 @@ iptr_2_long:
float_2_long:
.L38:
<entry-point>
- cast.64 %r59 <- (32) %arg1
+ fcvts.64 %r59 <- (32) %arg1
ret.64 %r59
double_2_long:
.L40:
<entry-point>
- ret.64 %arg1
+ fcvts.64 %r62 <- (64) %arg1
+ ret.64 %r62
int_2_ulong:
@@ -236,14 +239,15 @@ iptr_2_ulong:
float_2_ulong:
.L52:
<entry-point>
- cast.64 %r80 <- (32) %arg1
+ fcvtu.64 %r80 <- (32) %arg1
ret.64 %r80
double_2_ulong:
.L54:
<entry-point>
- ret.64 %arg1
+ fcvtu.64 %r83 <- (64) %arg1
+ ret.64 %r83
int_2_vptr:
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 07/14] cast: specialize casts from unsigned to pointers
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (5 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 06/14] cast: specialize floats to integer conversion Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 08/14] cast: make [u]intptr_ctype alias of [s]size_t_ctype Luc Van Oostenryck
` (6 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently all casts to pointers are processed alike. This is
but rather uncovenient as it correspond to different operations
that may obey to different rules and which later need extra checks.
Change this by using a specific instructions (OP_UTPTR) for
unsigned integer to pointers.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 3 +++
cse.c | 2 ++
example.c | 2 ++
lib.c | 2 ++
lib.h | 1 +
linearize.c | 20 +++++++++++++++++-
linearize.h | 1 +
liveness.c | 1 +
simplify.c | 3 +++
sparse-llvm.c | 1 +
validation/cast-kinds-check.c | 2 ++
validation/cast-kinds.c | 13 ++++++++----
validation/cast-weirds.c | 49 +++++++++++++++++++++++++++++++++++++++++++
13 files changed, 95 insertions(+), 5 deletions(-)
create mode 100644 validation/cast-weirds.c
diff --git a/Documentation/IR.md b/Documentation/IR.md
index 0bfd9765c..039bdb097 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -163,6 +163,9 @@ Cast to unsigned integer (and to void pointer).
### OP_SCAST
Cast to signed integer.
+### OP_UTPTR
+Cast from unsigned integer to pointer type.
+
### OP_PTRCAST
Cast to pointer.
diff --git a/cse.c b/cse.c
index 17b3da01a..3e5d493d1 100644
--- a/cse.c
+++ b/cse.c
@@ -89,6 +89,7 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
case OP_CAST:
case OP_SCAST:
case OP_PTRCAST:
+ case OP_UTPTR:
/*
* This is crap! Many "orig_types" are the
* same as far as casts go, we should generate
@@ -233,6 +234,7 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_CAST:
case OP_SCAST:
case OP_PTRCAST:
+ case OP_UTPTR:
/*
* This is crap! See the comments on hashing.
*/
diff --git a/example.c b/example.c
index 0349a7e20..18eef6627 100644
--- a/example.c
+++ b/example.c
@@ -88,6 +88,7 @@ static const char *opcodes[] = {
[OP_UCVTF] = "ucvtf",
[OP_SCVTF] = "scvtf",
[OP_FCVTF] = "fcvtf",
+ [OP_UTPTR] = "utptr",
[OP_PTRCAST] = "ptrcast",
[OP_CALL] = "call",
[OP_VANEXT] = "va_next",
@@ -1425,6 +1426,7 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
break;
case OP_CAST: case OP_SCAST: case OP_PTRCAST:
+ case OP_UTPTR:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
diff --git a/lib.c b/lib.c
index 73e9a2fe6..1c67e1912 100644
--- a/lib.c
+++ b/lib.c
@@ -230,6 +230,7 @@ int Wdefault_bitfield_sign = 0;
int Wdesignated_init = 1;
int Wdo_while = 0;
int Winit_cstring = 0;
+int Wint_to_pointer_cast = 1;
int Wenum_mismatch = 1;
int Wsparse_error = 0;
int Wmemcpy_max_count = 1;
@@ -523,6 +524,7 @@ static const struct warning {
{ "do-while", &Wdo_while },
{ "enum-mismatch", &Wenum_mismatch },
{ "init-cstring", &Winit_cstring },
+ { "int-to-pointer-cast", &Wint_to_pointer_cast },
{ "memcpy-max-count", &Wmemcpy_max_count },
{ "non-pointer-null", &Wnon_pointer_null },
{ "old-initializer", &Wold_initializer },
diff --git a/lib.h b/lib.h
index 307ccaeb2..010317970 100644
--- a/lib.h
+++ b/lib.h
@@ -125,6 +125,7 @@ extern int Wdo_while;
extern int Wenum_mismatch;
extern int Wsparse_error;
extern int Winit_cstring;
+extern int Wint_to_pointer_cast;
extern int Wmemcpy_max_count;
extern int Wnon_pointer_null;
extern int Wold_initializer;
diff --git a/linearize.c b/linearize.c
index 75b200c4b..85d472ca6 100644
--- a/linearize.c
+++ b/linearize.c
@@ -235,6 +235,7 @@ static const char *opcodes[] = {
[OP_UCVTF] = "ucvtf",
[OP_SCVTF] = "scvtf",
[OP_FCVTF] = "fcvtf",
+ [OP_UTPTR] = "utptr",
[OP_PTRCAST] = "ptrcast",
[OP_INLINED_CALL] = "# call",
[OP_CALL] = "call",
@@ -432,6 +433,7 @@ const char *show_instruction(struct instruction *insn)
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
+ case OP_UTPTR:
case OP_PTRCAST:
buf += sprintf(buf, "%s <- (%d) %s",
show_pseudo(insn->target),
@@ -1175,7 +1177,17 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
return OP_BADOP;
}
case MTYPE_PTR:
- return OP_PTRCAST;
+ switch (stype) {
+ case MTYPE_UINT:
+ case MTYPE_SINT:
+ if (is_ptr_type(src)) // must be a void pointer
+ return OP_PTRCAST;// FIXME: to be removed?
+ return OP_UTPTR;
+ case MTYPE_PTR:
+ return OP_PTRCAST;
+ default:
+ return OP_BADOP;
+ }
case MTYPE_UINT:
case MTYPE_SINT:
switch (stype) {
@@ -1208,6 +1220,12 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
switch (opcode) {
case OP_NOP:
return src;
+ case OP_UTPTR:
+ if (from->bit_size == to->bit_size)
+ break;
+ if (Wint_to_pointer_cast)
+ warning(to->pos, "non size-preserving integer to pointer cast");
+ break;
default:
break;
}
diff --git a/linearize.h b/linearize.h
index 600bae598..3570f1507 100644
--- a/linearize.h
+++ b/linearize.h
@@ -201,6 +201,7 @@ enum opcode {
OP_FCVTU, OP_FCVTS,
OP_UCVTF, OP_SCVTF,
OP_FCVTF,
+ OP_UTPTR,
OP_PTRCAST,
OP_INLINED_CALL,
OP_CALL,
diff --git a/liveness.c b/liveness.c
index 3bd95fe5b..b9c6e4017 100644
--- a/liveness.c
+++ b/liveness.c
@@ -116,6 +116,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
+ case OP_UTPTR:
case OP_PTRCAST:
USES(src); DEFINES(target);
break;
diff --git a/simplify.c b/simplify.c
index 365811b96..f8222d31b 100644
--- a/simplify.c
+++ b/simplify.c
@@ -241,6 +241,7 @@ void kill_insn(struct instruction *insn, int force)
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
+ case OP_UTPTR:
case OP_PTRCAST:
case OP_SETVAL:
case OP_NOT: case OP_NEG:
@@ -345,6 +346,7 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo)
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
+ case OP_UTPTR:
case OP_PTRCAST:
kill_use(&insn->src1);
break;
@@ -1208,6 +1210,7 @@ int simplify_instruction(struct instruction *insn)
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
+ case OP_UTPTR:
case OP_PTRCAST:
return simplify_cast(insn);
case OP_PHI:
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 04efc6637..f4567a5f7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -860,6 +860,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
case OP_FCVTF:
assert(0);
break;
+ case OP_UTPTR:
case OP_PTRCAST:
output_op_ptrcast(fn, insn);
break;
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index be6b684b4..365fe6e40 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -20,5 +20,7 @@ cast-kinds.c:29:51: warning: cast wasn't removed
cast-kinds.c:34:52: warning: cast wasn't removed
cast-kinds.c:35:54: warning: cast wasn't removed
cast-kinds.c:36:52: warning: cast wasn't removed
+cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast
+cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast
* check-error-end
*/
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index d07a94190..e5b64b768 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -57,6 +57,11 @@ static double double_2_double(double a) { return a; }
* check-name: cast-kinds
* check-command: test-linearize -m64 $file
*
+ * check-error-start
+cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast
+cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast
+ * check-error-end
+ *
* check-output-start
uint_2_int:
.L0:
@@ -288,28 +293,28 @@ iptr_2_vptr:
int_2_iptr:
.L66:
<entry-point>
- ptrcast.64 %r101 <- (32) %arg1
+ utptr.64 %r101 <- (32) %arg1
ret.64 %r101
uint_2_iptr:
.L68:
<entry-point>
- ptrcast.64 %r104 <- (32) %arg1
+ utptr.64 %r104 <- (32) %arg1
ret.64 %r104
long_2_iptr:
.L70:
<entry-point>
- ptrcast.64 %r107 <- (64) %arg1
+ utptr.64 %r107 <- (64) %arg1
ret.64 %r107
ulong_2_iptr:
.L72:
<entry-point>
- ptrcast.64 %r110 <- (64) %arg1
+ utptr.64 %r110 <- (64) %arg1
ret.64 %r110
diff --git a/validation/cast-weirds.c b/validation/cast-weirds.c
new file mode 100644
index 000000000..136137b4c
--- /dev/null
+++ b/validation/cast-weirds.c
@@ -0,0 +1,49 @@
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+static int * int_2_iptr(int a) { return (int *)a; }
+static int * uint_2_iptr(uint a) { return (int *)a; }
+
+static void * int_2_vptr(int a) { return (void *)a; }
+static void * uint_2_vptr(uint a) { return (void *)a; }
+
+/*
+ * check-name: cast-weirds
+ * check-command: test-linearize -m64 $file
+ *
+ * check-error-start
+cast-weirds.c:4:42: warning: non size-preserving integer to pointer cast
+cast-weirds.c:5:44: warning: non size-preserving integer to pointer cast
+ * check-error-end
+ *
+ * check-output-start
+int_2_iptr:
+.L0:
+ <entry-point>
+ utptr.64 %r2 <- (32) %arg1
+ ret.64 %r2
+
+
+uint_2_iptr:
+.L2:
+ <entry-point>
+ utptr.64 %r5 <- (32) %arg1
+ ret.64 %r5
+
+
+int_2_vptr:
+.L4:
+ <entry-point>
+ scast.64 %r8 <- (32) %arg1
+ ret.64 %r8
+
+
+uint_2_vptr:
+.L6:
+ <entry-point>
+ cast.64 %r11 <- (32) %arg1
+ ret.64 %r11
+
+
+ * check-output-end
+ */
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 08/14] cast: make [u]intptr_ctype alias of [s]size_t_ctype
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (6 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 07/14] cast: specialize casts from unsigned to pointers Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 09/14] cast: make pointer casts always size preserving Luc Van Oostenryck
` (5 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
When processing integer to/from pointers, we would like to have
an integer type which has the same size as a pointer.
Currently, it's always th case for [s]size_t but it's preferable
to have a specific type which will always offer this guarantee,
like [u]intptr_t.
Fix this lazily by defining [u]intptr_ctype to [s]size_t_ctype.
Note: this intptr_t is just internal to sparse and can be different
from the type choosen by the libc/platform.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
symbol.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/symbol.h b/symbol.h
index 327449611..3e343e41e 100644
--- a/symbol.h
+++ b/symbol.h
@@ -270,6 +270,9 @@ extern struct symbol bool_ctype, void_ctype, type_ctype,
incomplete_ctype, label_ctype, bad_ctype,
null_ctype;
+#define uintptr_ctype size_t_ctype
+#define intptr_ctype ssize_t_ctype
+
/* Special internal symbols */
extern struct symbol zero_int;
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 09/14] cast: make pointer casts always size preserving
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (7 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 08/14] cast: make [u]intptr_ctype alias of [s]size_t_ctype Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 10/14] cast: temporary simplify handling cast to/from void* Luc Van Oostenryck
` (4 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently casts to pointers can be done from any integer type.
However, casts to (or from) pointers are only meaningful if value
preserving and thus between object of the same size.
To avoid to have to worry about sign/zero extension while doing
casts to pointers it's good to not have to deal with such casts.
Do this by doing first, if needed, a cast an integer of the same
size as a pointer before doing the cast to a pointer.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 2 +-
linearize.c | 2 ++
validation/cast-kinds.c | 62 +++++++++++++++++++++++++-----------------------
validation/cast-weirds.c | 18 +++++++-------
4 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index 039bdb097..a1a32c562 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -164,7 +164,7 @@ Cast to unsigned integer (and to void pointer).
Cast to signed integer.
### OP_UTPTR
-Cast from unsigned integer to pointer type.
+Cast from pointer-sized unsigned integer to pointer type.
### OP_PTRCAST
Cast to pointer.
diff --git a/linearize.c b/linearize.c
index 85d472ca6..8be26db58 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1225,6 +1225,8 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
break;
if (Wint_to_pointer_cast)
warning(to->pos, "non size-preserving integer to pointer cast");
+ src = cast_pseudo(ep, src, from, size_t_ctype);
+ from = size_t_ctype;
break;
default:
break;
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index e5b64b768..aa9f9bb29 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -293,106 +293,108 @@ iptr_2_vptr:
int_2_iptr:
.L66:
<entry-point>
- utptr.64 %r101 <- (32) %arg1
- ret.64 %r101
+ scast.64 %r101 <- (32) %arg1
+ utptr.64 %r102 <- (64) %r101
+ ret.64 %r102
uint_2_iptr:
.L68:
<entry-point>
- utptr.64 %r104 <- (32) %arg1
- ret.64 %r104
+ cast.64 %r105 <- (32) %arg1
+ utptr.64 %r106 <- (64) %r105
+ ret.64 %r106
long_2_iptr:
.L70:
<entry-point>
- utptr.64 %r107 <- (64) %arg1
- ret.64 %r107
+ utptr.64 %r109 <- (64) %arg1
+ ret.64 %r109
ulong_2_iptr:
.L72:
<entry-point>
- utptr.64 %r110 <- (64) %arg1
- ret.64 %r110
+ utptr.64 %r112 <- (64) %arg1
+ ret.64 %r112
vptr_2_iptr:
.L74:
<entry-point>
- ptrcast.64 %r113 <- (64) %arg1
- ret.64 %r113
+ ptrcast.64 %r115 <- (64) %arg1
+ ret.64 %r115
int_2_float:
.L76:
<entry-point>
- scvtf.32 %r116 <- (32) %arg1
- ret.32 %r116
+ scvtf.32 %r118 <- (32) %arg1
+ ret.32 %r118
uint_2_float:
.L78:
<entry-point>
- ucvtf.32 %r119 <- (32) %arg1
- ret.32 %r119
+ ucvtf.32 %r121 <- (32) %arg1
+ ret.32 %r121
long_2_float:
.L80:
<entry-point>
- scvtf.32 %r122 <- (64) %arg1
- ret.32 %r122
+ scvtf.32 %r124 <- (64) %arg1
+ ret.32 %r124
ulong_2_float:
.L82:
<entry-point>
- ucvtf.32 %r125 <- (64) %arg1
- ret.32 %r125
+ ucvtf.32 %r127 <- (64) %arg1
+ ret.32 %r127
double_2_float:
.L84:
<entry-point>
- fcvtf.32 %r128 <- (64) %arg1
- ret.32 %r128
+ fcvtf.32 %r130 <- (64) %arg1
+ ret.32 %r130
int_2_double:
.L86:
<entry-point>
- scvtf.64 %r131 <- (32) %arg1
- ret.64 %r131
+ scvtf.64 %r133 <- (32) %arg1
+ ret.64 %r133
uint_2_double:
.L88:
<entry-point>
- ucvtf.64 %r134 <- (32) %arg1
- ret.64 %r134
+ ucvtf.64 %r136 <- (32) %arg1
+ ret.64 %r136
long_2_double:
.L90:
<entry-point>
- scvtf.64 %r137 <- (64) %arg1
- ret.64 %r137
+ scvtf.64 %r139 <- (64) %arg1
+ ret.64 %r139
ulong_2_double:
.L92:
<entry-point>
- ucvtf.64 %r140 <- (64) %arg1
- ret.64 %r140
+ ucvtf.64 %r142 <- (64) %arg1
+ ret.64 %r142
float_2_double:
.L94:
<entry-point>
- fcvtf.64 %r143 <- (32) %arg1
- ret.64 %r143
+ fcvtf.64 %r145 <- (32) %arg1
+ ret.64 %r145
float_2_float:
diff --git a/validation/cast-weirds.c b/validation/cast-weirds.c
index 136137b4c..71e52ff57 100644
--- a/validation/cast-weirds.c
+++ b/validation/cast-weirds.c
@@ -20,29 +20,31 @@ cast-weirds.c:5:44: warning: non size-preserving integer to pointer cast
int_2_iptr:
.L0:
<entry-point>
- utptr.64 %r2 <- (32) %arg1
- ret.64 %r2
+ scast.64 %r2 <- (32) %arg1
+ utptr.64 %r3 <- (64) %r2
+ ret.64 %r3
uint_2_iptr:
.L2:
<entry-point>
- utptr.64 %r5 <- (32) %arg1
- ret.64 %r5
+ cast.64 %r6 <- (32) %arg1
+ utptr.64 %r7 <- (64) %r6
+ ret.64 %r7
int_2_vptr:
.L4:
<entry-point>
- scast.64 %r8 <- (32) %arg1
- ret.64 %r8
+ scast.64 %r10 <- (32) %arg1
+ ret.64 %r10
uint_2_vptr:
.L6:
<entry-point>
- cast.64 %r11 <- (32) %arg1
- ret.64 %r11
+ cast.64 %r13 <- (32) %arg1
+ ret.64 %r13
* check-output-end
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 10/14] cast: temporary simplify handling cast to/from void*
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (8 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 09/14] cast: make pointer casts always size preserving Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 11/14] cast: specialize cast from pointers Luc Van Oostenryck
` (3 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently pointer cast from/to void are treated as casts
to/from integer. The rationale being that a void pointer can't
anyway be dereferenced.
Allow to contnue to do by using a new 'machine type' for void
pointer which then allow to select the right type of cast:
OP_PTRCAST or OP_[S]CAST.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
linearize.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/linearize.c b/linearize.c
index 8be26db58..01e6abde8 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1121,6 +1121,7 @@ enum mtype {
MTYPE_UINT,
MTYPE_SINT,
MTYPE_PTR,
+ MTYPE_VPTR, // TODO: must be removed ?
MTYPE_FLOAT,
MTYPE_BAD,
};
@@ -1135,8 +1136,7 @@ retry: switch (s->type) {
goto retry;
case SYM_PTR:
if (s->ctype.base_type == &void_ctype)
- // handle void pointer like an uint
- goto case_int;
+ return MTYPE_VPTR;
return MTYPE_PTR;
case SYM_BITFIELD:
case SYM_RESTRICT:
@@ -1180,14 +1180,25 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
switch (stype) {
case MTYPE_UINT:
case MTYPE_SINT:
- if (is_ptr_type(src)) // must be a void pointer
- return OP_PTRCAST;// FIXME: to be removed?
return OP_UTPTR;
case MTYPE_PTR:
+ case MTYPE_VPTR:
return OP_PTRCAST;
default:
return OP_BADOP;
}
+ case MTYPE_VPTR:
+ switch (stype) {
+ case MTYPE_PTR:
+ case MTYPE_VPTR:
+ case MTYPE_UINT:
+ return OP_CAST;
+ case MTYPE_SINT:
+ return OP_SCAST;
+ default:
+ return OP_BADOP;
+ break;
+ }
case MTYPE_UINT:
case MTYPE_SINT:
switch (stype) {
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 11/14] cast: specialize cast from pointers
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (9 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 10/14] cast: temporary simplify handling cast to/from void* Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 12/14] cast: add support for -Wpointer-to-int-cast Luc Van Oostenryck
` (2 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently all casts to pointers are processed alike. This is
simple creating the cast but rather uncovenient in later phases
as this correspond to different operations that may obey to
different rules and which later need extra checks.
Change this by using a specific instructions (OP_UTPTR) for
[unsigned] integer to pointers.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 10 ++++++++--
cse.c | 4 ++--
example.c | 2 ++
linearize.c | 7 +++++++
linearize.h | 1 +
liveness.c | 1 +
simplify.c | 3 +++
sparse-llvm.c | 1 +
sparse.c | 1 +
validation/cast-kinds.c | 8 ++++----
10 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index a1a32c562..8f7083ea4 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -157,8 +157,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_CAST
-Cast to unsigned integer (and to void pointer).
+Cast to unsigned integer.
### OP_SCAST
Cast to signed integer.
@@ -166,8 +169,11 @@ Cast to signed integer.
### OP_UTPTR
Cast from pointer-sized unsigned integer to pointer type.
+### OP_PTRTU
+Cast from pointer type to unsigned integer.
+
### OP_PTRCAST
-Cast to pointer.
+Cast between pointer.
### OP_FCVTU
Conversion from float type to unsigned integer.
diff --git a/cse.c b/cse.c
index 3e5d493d1..166b7cda6 100644
--- a/cse.c
+++ b/cse.c
@@ -89,7 +89,7 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
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
@@ -234,7 +234,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 18eef6627..3a0ec0747 100644
--- a/example.c
+++ b/example.c
@@ -89,6 +89,7 @@ static const char *opcodes[] = {
[OP_SCVTF] = "scvtf",
[OP_FCVTF] = "fcvtf",
[OP_UTPTR] = "utptr",
+ [OP_PTRTU] = "utptr",
[OP_PTRCAST] = "ptrcast",
[OP_CALL] = "call",
[OP_VANEXT] = "va_next",
@@ -1427,6 +1428,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 01e6abde8..a1b647864 100644
--- a/linearize.c
+++ b/linearize.c
@@ -236,6 +236,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",
@@ -434,6 +435,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),
@@ -1204,6 +1206,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 3570f1507..165d2b579 100644
--- a/linearize.h
+++ b/linearize.h
@@ -202,6 +202,7 @@ enum opcode {
OP_UCVTF, OP_SCVTF,
OP_FCVTF,
OP_UTPTR,
+ OP_PTRTU,
OP_PTRCAST,
OP_INLINED_CALL,
OP_CALL,
diff --git a/liveness.c b/liveness.c
index b9c6e4017..ef2030f3e 100644
--- a/liveness.c
+++ b/liveness.c
@@ -117,6 +117,7 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_UTPTR:
+ case OP_PTRTU:
case OP_PTRCAST:
USES(src); DEFINES(target);
break;
diff --git a/simplify.c b/simplify.c
index f8222d31b..86512cc84 100644
--- a/simplify.c
+++ b/simplify.c
@@ -242,6 +242,7 @@ void kill_insn(struct instruction *insn, int force)
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_UTPTR:
+ case OP_PTRTU:
case OP_PTRCAST:
case OP_SETVAL:
case OP_NOT: case OP_NEG:
@@ -347,6 +348,7 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo)
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_UTPTR:
+ case OP_PTRTU:
case OP_PTRCAST:
kill_use(&insn->src1);
break;
@@ -1211,6 +1213,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 f4567a5f7..8dd6a5185 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -861,6 +861,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
assert(0);
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 bceacd94e..9f9611e25 100644
--- a/sparse.c
+++ b/sparse.c
@@ -215,6 +215,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/cast-kinds.c b/validation/cast-kinds.c
index aa9f9bb29..f60013e68 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -93,7 +93,7 @@ vptr_2_int:
iptr_2_int:
.L8:
<entry-point>
- cast.32 %r14 <- (64) %arg1
+ ptrtu.32 %r14 <- (64) %arg1
ret.32 %r14
@@ -141,7 +141,7 @@ vptr_2_uint:
iptr_2_uint:
.L22:
<entry-point>
- cast.32 %r35 <- (64) %arg1
+ ptrtu.32 %r35 <- (64) %arg1
ret.32 %r35
@@ -189,7 +189,7 @@ vptr_2_long:
iptr_2_long:
.L36:
<entry-point>
- cast.64 %r56 <- (64) %arg1
+ ptrtu.64 %r56 <- (64) %arg1
ret.64 %r56
@@ -237,7 +237,7 @@ vptr_2_ulong:
iptr_2_ulong:
.L50:
<entry-point>
- cast.64 %r77 <- (64) %arg1
+ ptrtu.64 %r77 <- (64) %arg1
ret.64 %r77
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 12/14] cast: add support for -Wpointer-to-int-cast
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (10 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 11/14] cast: specialize cast from pointers Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 13/14] cast: make casts from pointer always size preserving Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 14/14] cast: specialize integer casts Luc Van Oostenryck
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
It's relatively common to cast a pointer to an unsigned long,
for example to make some bit operations.
It's much less sensicla to cast a pointer to an integer smaller
(or bigger) than a pointer is.
So allow to emit a diagnostic for this, under the control of a
new warning flag: -Wpointer-to-cast.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
lib.c | 2 ++
lib.h | 1 +
linearize.c | 5 +++++
validation/cast-kinds-check.c | 2 +-
validation/cast-kinds.c | 2 ++
5 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/lib.c b/lib.c
index 1c67e1912..7bfe9eb4e 100644
--- a/lib.c
+++ b/lib.c
@@ -241,6 +241,7 @@ int Woverride_init = 1;
int Woverride_init_all = 0;
int Woverride_init_whole_range = 0;
int Wparen_string = 0;
+int Wpointer_to_int_cast = 1;
int Wptr_subtraction_blows = 0;
int Wreturn_void = 0;
int Wshadow = 0;
@@ -532,6 +533,7 @@ static const struct warning {
{ "override-init", &Woverride_init },
{ "override-init-all", &Woverride_init_all },
{ "paren-string", &Wparen_string },
+ { "pointer-to-int-cast", &Wpointer_to_int_cast },
{ "ptr-subtraction-blows", &Wptr_subtraction_blows },
{ "return-void", &Wreturn_void },
{ "shadow", &Wshadow },
diff --git a/lib.h b/lib.h
index 010317970..e588bb8c5 100644
--- a/lib.h
+++ b/lib.h
@@ -134,6 +134,7 @@ extern int Woverride_init;
extern int Woverride_init_all;
extern int Woverride_init_whole_range;
extern int Wparen_string;
+extern int Wpointer_to_int_cast;
extern int Wptr_subtraction_blows;
extern int Wreturn_void;
extern int Wshadow;
diff --git a/linearize.c b/linearize.c
index a1b647864..cae402ad3 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1246,6 +1246,11 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
src = cast_pseudo(ep, src, from, size_t_ctype);
from = size_t_ctype;
break;
+ case OP_PTRTU:
+ if (from->bit_size == to->bit_size)
+ break;
+ if (Wpointer_to_int_cast)
+ warning(to->pos, "non size-preserving pointer to integer cast");
default:
break;
}
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index 365fe6e40..0eb94d047 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -2,7 +2,7 @@
/*
* check-name: cast-kinds check
- * check-command: sparse -m64 -v $file
+ * check-command: sparse -m64 -v -Wno-pointer-to-int-cast $file
*
* check-error-start
cast-kinds.c:5:45: warning: cast drops bits
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index f60013e68..747a181ce 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -58,6 +58,8 @@ static double double_2_double(double a) { return a; }
* check-command: test-linearize -m64 $file
*
* check-error-start
+cast-kinds.c:8:41: warning: non size-preserving pointer to integer cast
+cast-kinds.c:15:43: warning: non size-preserving pointer to integer cast
cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast
cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast
* check-error-end
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 13/14] cast: make casts from pointer always size preserving
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (11 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 12/14] cast: add support for -Wpointer-to-int-cast Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 14/14] cast: specialize integer casts Luc Van Oostenryck
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Currently casts from pointers can be done to any integer type.
However, casts to (or from) pointers are only meaningful if
it preserves the value and thus dince between same-sized objects.
To avoid to have to worry about sign/zero extension while doing
casts to pointers it's good to not have to deal with such casts.
Do this by doing first a cast to an unsigned integer of the same size
as a pointer and then, if needed, doing to cast to the final type.
As such we have only to support pointer cast to unsigned char of the
same size and on the other we have the generic integer-to-interger
casts we to support anyway.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 2 +-
linearize.c | 2 +
sparse.c | 1 -
validation/cast-kinds-check.c | 2 -
validation/cast-kinds.c | 170 +++++++++++++++++++++---------------------
5 files changed, 89 insertions(+), 88 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index 8f7083ea4..dcfd89bb6 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -170,7 +170,7 @@ Cast to signed integer.
Cast from pointer-sized unsigned integer to pointer type.
### OP_PTRTU
-Cast from pointer type to unsigned integer.
+Cast from pointer type to pointer sized unsigned integer.
### OP_PTRCAST
Cast between pointer.
diff --git a/linearize.c b/linearize.c
index cae402ad3..5d6cf7385 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1251,6 +1251,8 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
break;
if (Wpointer_to_int_cast)
warning(to->pos, "non size-preserving pointer to integer cast");
+ src = cast_pseudo(ep, src, from, size_t_ctype);
+ return cast_pseudo(ep, src, size_t_ctype, to);
default:
break;
}
diff --git a/sparse.c b/sparse.c
index 9f9611e25..bceacd94e 100644
--- a/sparse.c
+++ b/sparse.c
@@ -215,7 +215,6 @@ 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/cast-kinds-check.c b/validation/cast-kinds-check.c
index 0eb94d047..fe0f83e24 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -14,9 +14,7 @@ cast-kinds.c:13:50: warning: cast drops bits
cast-kinds.c:14:49: warning: cast drops bits
cast-kinds.c:15:48: warning: cast drops bits
cast-kinds.c:21:49: warning: cast wasn't removed
-cast-kinds.c:22:48: warning: cast wasn't removed
cast-kinds.c:28:52: warning: cast wasn't removed
-cast-kinds.c:29:51: warning: cast wasn't removed
cast-kinds.c:34:52: warning: cast wasn't removed
cast-kinds.c:35:54: warning: cast wasn't removed
cast-kinds.c:36:52: warning: cast wasn't removed
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index 747a181ce..3ac95c3dc 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -95,22 +95,23 @@ vptr_2_int:
iptr_2_int:
.L8:
<entry-point>
- ptrtu.32 %r14 <- (64) %arg1
- ret.32 %r14
+ ptrtu.64 %r14 <- (64) %arg1
+ cast.32 %r15 <- (64) %r14
+ ret.32 %r15
float_2_int:
.L10:
<entry-point>
- fcvts.32 %r17 <- (32) %arg1
- ret.32 %r17
+ fcvts.32 %r18 <- (32) %arg1
+ ret.32 %r18
double_2_int:
.L12:
<entry-point>
- fcvts.32 %r20 <- (64) %arg1
- ret.32 %r20
+ fcvts.32 %r21 <- (64) %arg1
+ ret.32 %r21
int_2_uint:
@@ -122,57 +123,58 @@ int_2_uint:
long_2_uint:
.L16:
<entry-point>
- scast.32 %r26 <- (64) %arg1
- ret.32 %r26
+ scast.32 %r27 <- (64) %arg1
+ ret.32 %r27
ulong_2_uint:
.L18:
<entry-point>
- cast.32 %r29 <- (64) %arg1
- ret.32 %r29
+ cast.32 %r30 <- (64) %arg1
+ ret.32 %r30
vptr_2_uint:
.L20:
<entry-point>
- cast.32 %r32 <- (64) %arg1
- ret.32 %r32
+ cast.32 %r33 <- (64) %arg1
+ ret.32 %r33
iptr_2_uint:
.L22:
<entry-point>
- ptrtu.32 %r35 <- (64) %arg1
- ret.32 %r35
+ ptrtu.64 %r36 <- (64) %arg1
+ cast.32 %r37 <- (64) %r36
+ ret.32 %r37
float_2_uint:
.L24:
<entry-point>
- fcvtu.32 %r38 <- (32) %arg1
- ret.32 %r38
+ fcvtu.32 %r40 <- (32) %arg1
+ ret.32 %r40
double_2_uint:
.L26:
<entry-point>
- fcvtu.32 %r41 <- (64) %arg1
- ret.32 %r41
+ fcvtu.32 %r43 <- (64) %arg1
+ ret.32 %r43
int_2_long:
.L28:
<entry-point>
- scast.64 %r44 <- (32) %arg1
- ret.64 %r44
+ scast.64 %r46 <- (32) %arg1
+ ret.64 %r46
uint_2_long:
.L30:
<entry-point>
- cast.64 %r47 <- (32) %arg1
- ret.64 %r47
+ cast.64 %r49 <- (32) %arg1
+ ret.64 %r49
ulong_2_long:
@@ -184,43 +186,43 @@ ulong_2_long:
vptr_2_long:
.L34:
<entry-point>
- cast.64 %r53 <- (64) %arg1
- ret.64 %r53
+ cast.64 %r55 <- (64) %arg1
+ ret.64 %r55
iptr_2_long:
.L36:
<entry-point>
- ptrtu.64 %r56 <- (64) %arg1
- ret.64 %r56
+ ptrtu.64 %r58 <- (64) %arg1
+ ret.64 %r58
float_2_long:
.L38:
<entry-point>
- fcvts.64 %r59 <- (32) %arg1
- ret.64 %r59
+ fcvts.64 %r61 <- (32) %arg1
+ ret.64 %r61
double_2_long:
.L40:
<entry-point>
- fcvts.64 %r62 <- (64) %arg1
- ret.64 %r62
+ fcvts.64 %r64 <- (64) %arg1
+ ret.64 %r64
int_2_ulong:
.L42:
<entry-point>
- scast.64 %r65 <- (32) %arg1
- ret.64 %r65
+ scast.64 %r67 <- (32) %arg1
+ ret.64 %r67
uint_2_ulong:
.L44:
<entry-point>
- cast.64 %r68 <- (32) %arg1
- ret.64 %r68
+ cast.64 %r70 <- (32) %arg1
+ ret.64 %r70
long_2_ulong:
@@ -232,171 +234,171 @@ long_2_ulong:
vptr_2_ulong:
.L48:
<entry-point>
- cast.64 %r74 <- (64) %arg1
- ret.64 %r74
+ cast.64 %r76 <- (64) %arg1
+ ret.64 %r76
iptr_2_ulong:
.L50:
<entry-point>
- ptrtu.64 %r77 <- (64) %arg1
- ret.64 %r77
+ ptrtu.64 %r79 <- (64) %arg1
+ ret.64 %r79
float_2_ulong:
.L52:
<entry-point>
- fcvtu.64 %r80 <- (32) %arg1
- ret.64 %r80
+ fcvtu.64 %r82 <- (32) %arg1
+ ret.64 %r82
double_2_ulong:
.L54:
<entry-point>
- fcvtu.64 %r83 <- (64) %arg1
- ret.64 %r83
+ fcvtu.64 %r85 <- (64) %arg1
+ ret.64 %r85
int_2_vptr:
.L56:
<entry-point>
- scast.64 %r86 <- (32) %arg1
- ret.64 %r86
+ scast.64 %r88 <- (32) %arg1
+ ret.64 %r88
uint_2_vptr:
.L58:
<entry-point>
- cast.64 %r89 <- (32) %arg1
- ret.64 %r89
+ cast.64 %r91 <- (32) %arg1
+ ret.64 %r91
long_2_vptr:
.L60:
<entry-point>
- scast.64 %r92 <- (64) %arg1
- ret.64 %r92
+ scast.64 %r94 <- (64) %arg1
+ ret.64 %r94
ulong_2_vptr:
.L62:
<entry-point>
- cast.64 %r95 <- (64) %arg1
- ret.64 %r95
+ cast.64 %r97 <- (64) %arg1
+ ret.64 %r97
iptr_2_vptr:
.L64:
<entry-point>
- cast.64 %r98 <- (64) %arg1
- ret.64 %r98
+ cast.64 %r100 <- (64) %arg1
+ ret.64 %r100
int_2_iptr:
.L66:
<entry-point>
- scast.64 %r101 <- (32) %arg1
- utptr.64 %r102 <- (64) %r101
- ret.64 %r102
+ scast.64 %r103 <- (32) %arg1
+ utptr.64 %r104 <- (64) %r103
+ ret.64 %r104
uint_2_iptr:
.L68:
<entry-point>
- cast.64 %r105 <- (32) %arg1
- utptr.64 %r106 <- (64) %r105
- ret.64 %r106
+ cast.64 %r107 <- (32) %arg1
+ utptr.64 %r108 <- (64) %r107
+ ret.64 %r108
long_2_iptr:
.L70:
<entry-point>
- utptr.64 %r109 <- (64) %arg1
- ret.64 %r109
+ utptr.64 %r111 <- (64) %arg1
+ ret.64 %r111
ulong_2_iptr:
.L72:
<entry-point>
- utptr.64 %r112 <- (64) %arg1
- ret.64 %r112
+ utptr.64 %r114 <- (64) %arg1
+ ret.64 %r114
vptr_2_iptr:
.L74:
<entry-point>
- ptrcast.64 %r115 <- (64) %arg1
- ret.64 %r115
+ ptrcast.64 %r117 <- (64) %arg1
+ ret.64 %r117
int_2_float:
.L76:
<entry-point>
- scvtf.32 %r118 <- (32) %arg1
- ret.32 %r118
+ scvtf.32 %r120 <- (32) %arg1
+ ret.32 %r120
uint_2_float:
.L78:
<entry-point>
- ucvtf.32 %r121 <- (32) %arg1
- ret.32 %r121
+ ucvtf.32 %r123 <- (32) %arg1
+ ret.32 %r123
long_2_float:
.L80:
<entry-point>
- scvtf.32 %r124 <- (64) %arg1
- ret.32 %r124
+ scvtf.32 %r126 <- (64) %arg1
+ ret.32 %r126
ulong_2_float:
.L82:
<entry-point>
- ucvtf.32 %r127 <- (64) %arg1
- ret.32 %r127
+ ucvtf.32 %r129 <- (64) %arg1
+ ret.32 %r129
double_2_float:
.L84:
<entry-point>
- fcvtf.32 %r130 <- (64) %arg1
- ret.32 %r130
+ fcvtf.32 %r132 <- (64) %arg1
+ ret.32 %r132
int_2_double:
.L86:
<entry-point>
- scvtf.64 %r133 <- (32) %arg1
- ret.64 %r133
+ scvtf.64 %r135 <- (32) %arg1
+ ret.64 %r135
uint_2_double:
.L88:
<entry-point>
- ucvtf.64 %r136 <- (32) %arg1
- ret.64 %r136
+ ucvtf.64 %r138 <- (32) %arg1
+ ret.64 %r138
long_2_double:
.L90:
<entry-point>
- scvtf.64 %r139 <- (64) %arg1
- ret.64 %r139
+ scvtf.64 %r141 <- (64) %arg1
+ ret.64 %r141
ulong_2_double:
.L92:
<entry-point>
- ucvtf.64 %r142 <- (64) %arg1
- ret.64 %r142
+ ucvtf.64 %r144 <- (64) %arg1
+ ret.64 %r144
float_2_double:
.L94:
<entry-point>
- fcvtf.64 %r145 <- (32) %arg1
- ret.64 %r145
+ fcvtf.64 %r147 <- (32) %arg1
+ ret.64 %r147
float_2_float:
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 14/14] cast: specialize integer casts
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
` (12 preceding siblings ...)
2017-08-17 4:05 ` [RFC PATCH 13/14] cast: make casts from pointer always size preserving Luc Van Oostenryck
@ 2017-08-17 4:05 ` Luc Van Oostenryck
13 siblings, 0 replies; 16+ messages in thread
From: Luc Van Oostenryck @ 2017-08-17 4:05 UTC (permalink / raw)
To: linux-sparse
Cc: Linus Torvalds, Christopher Li, Dibyendu Majumdar,
Luc Van Oostenryck
Aoo cast to unsigned integer and signed integer used to be
done with 2 instructions: OP_CAST & OP_SCAST.
Those are not very convenient as they don't reflect the real
operation that need to be done.
This patch specialize thises instruction in 4:
- OP_TRUNC, for casts to a smaller type
- OP_ZEXT, for cast that need a zero extension
- OP_SEXT, for cast that need a sign extension
Integer-to-integer casts of the same size are treated
as a NOP and in fact are never emitted.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
Documentation/IR.md | 11 +-
cse.c | 8 +-
example.c | 9 +-
linearize.c | 27 +++--
linearize.h | 5 +-
liveness.c | 4 +-
simplify.c | 36 +++----
sparse-llvm.c | 15 ++-
sparse.c | 5 +-
validation/bitfield-size.c | 5 +-
validation/builtin-bswap-variable.c | 4 +-
validation/cast-kinds-check.c | 5 -
validation/cast-kinds.c | 179 ++++++++++++++++-----------------
validation/cast-weirds.c | 8 +-
validation/compound-assign-type.c | 3 +-
validation/linear/bitfield-init-zero.c | 8 +-
validation/memops-volatile.c | 4 +-
validation/optim/bool-simplify.c | 4 +-
18 files changed, 171 insertions(+), 169 deletions(-)
diff --git a/Documentation/IR.md b/Documentation/IR.md
index dcfd89bb6..e0299aba0 100644
--- a/Documentation/IR.md
+++ b/Documentation/IR.md
@@ -160,11 +160,14 @@ They all have the following signature:
Currently, a cast to a void pointer is treated like a
cast to an unsigned integer of the same size.
-### OP_CAST
-Cast to unsigned integer.
+### OP_TRUNC
+Cast from integer to an integer of a smaller size.
-### OP_SCAST
-Cast to signed integer.
+### OP_SEXT
+Cast from integer to an integer of a bigger size with sign extension.
+
+### OP_ZEXT
+Cast from integer to an integer of a bigger size with zero extension.
### OP_UTPTR
Cast from pointer-sized unsigned integer to pointer type.
diff --git a/cse.c b/cse.c
index 166b7cda6..790e7b663 100644
--- a/cse.c
+++ b/cse.c
@@ -86,8 +86,8 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
hash += hashval(insn->symbol);
break;
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_PTRCAST:
case OP_UTPTR: case OP_PTRTU:
/*
@@ -231,8 +231,8 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_PHI:
return phi_list_compare(i1->phi_list, i2->phi_list);
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_PTRCAST:
case OP_UTPTR: case OP_PTRTU:
/*
diff --git a/example.c b/example.c
index 3a0ec0747..7192fc462 100644
--- a/example.c
+++ b/example.c
@@ -81,8 +81,9 @@ static const char *opcodes[] = {
[OP_PHI] = "phi",
[OP_PHISOURCE] = "phisrc",
[OP_COPY] = "copy",
- [OP_CAST] = "cast",
- [OP_SCAST] = "scast",
+ [OP_SEXT] = "sext",
+ [OP_ZEXT] = "zext",
+ [OP_TRUNC] = "trunc",
[OP_FCVTU] = "fcvtu",
[OP_FCVTS] = "fcvts",
[OP_UCVTF] = "ucvtf",
@@ -1426,7 +1427,9 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
generate_compare(state, insn);
break;
- case OP_CAST: case OP_SCAST: case OP_PTRCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
+ case OP_PTRCAST:
case OP_UTPTR:
case OP_PTRTU:
case OP_FCVTU: case OP_FCVTS:
diff --git a/linearize.c b/linearize.c
index 5d6cf7385..da33fe09b 100644
--- a/linearize.c
+++ b/linearize.c
@@ -228,8 +228,9 @@ static const char *opcodes[] = {
/* Other */
[OP_PHI] = "phi",
[OP_PHISOURCE] = "phisrc",
- [OP_CAST] = "cast",
- [OP_SCAST] = "scast",
+ [OP_SEXT] = "sext",
+ [OP_ZEXT] = "zext",
+ [OP_TRUNC] = "trunc",
[OP_FCVTU] = "fcvtu",
[OP_FCVTS] = "fcvts",
[OP_UCVTF] = "ucvtf",
@@ -429,8 +430,8 @@ const char *show_instruction(struct instruction *insn)
} END_FOR_EACH_PTR(arg);
break;
}
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
@@ -1194,13 +1195,14 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
case MTYPE_PTR:
case MTYPE_VPTR:
case MTYPE_UINT:
- return OP_CAST;
+ stype = MTYPE_UINT;
+ /* fall through */
case MTYPE_SINT:
- return OP_SCAST;
+ break;
default:
return OP_BADOP;
- break;
}
+ /* fall through */
case MTYPE_UINT:
case MTYPE_SINT:
switch (stype) {
@@ -1210,15 +1212,18 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
return OP_PTRTU;
case MTYPE_VPTR:
case MTYPE_UINT:
- return OP_CAST;
case MTYPE_SINT:
- return OP_SCAST;
+ if (dst->bit_size ==src->bit_size)
+ return OP_NOP;
+ if (dst->bit_size < src->bit_size)
+ return OP_TRUNC;
+ return stype == MTYPE_SINT ? OP_SEXT : OP_ZEXT;
default:
- break;
+ return OP_BADOP;
}
/* fall through */
default:
- return OP_CAST;
+ return OP_BADOP;
}
}
diff --git a/linearize.h b/linearize.h
index 165d2b579..5f2c94e86 100644
--- a/linearize.h
+++ b/linearize.h
@@ -196,8 +196,9 @@ enum opcode {
/* Other */
OP_PHI,
OP_PHISOURCE,
- OP_CAST,
- OP_SCAST,
+ OP_SEXT,
+ OP_ZEXT,
+ OP_TRUNC,
OP_FCVTU, OP_FCVTS,
OP_UCVTF, OP_SCVTF,
OP_FCVTF,
diff --git a/liveness.c b/liveness.c
index ef2030f3e..bf98bcca0 100644
--- a/liveness.c
+++ b/liveness.c
@@ -111,8 +111,8 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
USES(phi_src);
break;
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
diff --git a/simplify.c b/simplify.c
index 86512cc84..dcd29f427 100644
--- a/simplify.c
+++ b/simplify.c
@@ -236,8 +236,8 @@ void kill_insn(struct instruction *insn, int force)
kill_use(&insn->src2);
/* fall through */
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
@@ -342,8 +342,8 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo)
case OP_NOT:
case OP_NEG:
case OP_SYMADDR:
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
@@ -386,7 +386,7 @@ static unsigned int operand_size(struct instruction *insn, pseudo_t pseudo)
if (pseudo->type == PSEUDO_REG) {
struct instruction *src = pseudo->def;
- if (src && src->opcode == OP_CAST && src->orig_type) {
+ if (src && src->opcode == OP_ZEXT && src->orig_type) {
unsigned int orig_size = src->orig_type->bit_size;
if (orig_size < size)
size = orig_size;
@@ -978,11 +978,14 @@ static int simplify_cast(struct instruction *insn)
}
if (size == orig_size) {
- int op = (orig_type->ctype.modifiers & MOD_SIGNED) ? OP_SCAST : OP_CAST;
- if (insn->opcode == op)
- goto simplify;
- if (insn->opcode == OP_FCVTF)
+ switch (insn->opcode) {
+ //case OP_NOPCAST: // FIXME: what to do?
+ //case OP_PTRCAST: // FIXME: what to do?
+ case OP_FCVTF:
goto simplify;
+ default:
+ break;
+ }
}
return 0;
@@ -1131,13 +1134,10 @@ static int simplify_branch(struct instruction *insn)
return REPEAT_CSE;
}
}
- if (def->opcode == OP_CAST || def->opcode == OP_SCAST) {
- int orig_size = def->orig_type ? def->orig_type->bit_size : 0;
- if (def->size > orig_size) {
- use_pseudo(insn, def->src, &insn->cond);
- remove_usage(cond, &insn->cond);
- return REPEAT_CSE;
- }
+ if (def->opcode == OP_SEXT || def->opcode == OP_ZEXT) {
+ use_pseudo(insn, def->src, &insn->cond);
+ remove_usage(cond, &insn->cond);
+ return REPEAT_CSE;
}
}
return 0;
@@ -1207,8 +1207,8 @@ int simplify_instruction(struct instruction *insn)
if (dead_insn(insn, NULL, NULL, NULL))
return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
return replace_with_pseudo(insn, insn->symbol);
- case OP_CAST:
- case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 8dd6a5185..debf0cb7a 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -790,13 +790,7 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
src = pseudo_to_value(fn, insn, insn->src);
pseudo_name(insn->target, target_name);
-
- assert(!symbol_is_fp_type(insn->type));
-
- if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
- target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
- else
- target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
+ target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
insn->target->priv = target;
}
@@ -849,12 +843,15 @@ static void output_insn(struct function *fn, struct instruction *insn)
case OP_CALL:
output_op_call(fn, insn);
break;
- case OP_CAST:
+ case OP_ZEXT:
output_op_cast(fn, insn, LLVMZExt);
break;
- case OP_SCAST:
+ case OP_SEXT:
output_op_cast(fn, insn, LLVMSExt);
break;
+ case OP_TRUNC:
+ output_op_cast(fn, insn, LLVMTrunc);
+ break;
case OP_FCVTU: case OP_FCVTS:
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
diff --git a/sparse.c b/sparse.c
index bceacd94e..b4d14aeec 100644
--- a/sparse.c
+++ b/sparse.c
@@ -120,7 +120,7 @@ static void check_cast_instruction(struct instruction *insn)
int old = orig_type->bit_size;
int new = insn->size;
int oldsigned = (orig_type->ctype.modifiers & MOD_SIGNED) != 0;
- int newsigned = insn->opcode == OP_SCAST;
+ int newsigned = insn->opcode == OP_SEXT;
if (new > old) {
if (oldsigned == newsigned)
@@ -214,7 +214,8 @@ static void check_call_instruction(struct instruction *insn)
static void check_one_instruction(struct instruction *insn)
{
switch (insn->opcode) {
- case OP_CAST: case OP_SCAST:
+ case OP_SEXT: case OP_ZEXT:
+ case OP_TRUNC:
if (verbose)
check_cast_instruction(insn);
break;
diff --git a/validation/bitfield-size.c b/validation/bitfield-size.c
index ce78ecf21..c708a52db 100644
--- a/validation/bitfield-size.c
+++ b/validation/bitfield-size.c
@@ -35,7 +35,8 @@ unsigned int get_pbfi_b(struct bfi *bf) { return bf->b; }
* check-command: test-linearize -Wno-decl $file
* check-output-ignore
*
- * check-output-pattern-24-times: cast\\.
- * check-output-pattern-12-times: cast\\.4
+ * check-output-pattern-8-times: zext\\.
+ * check-output-pattern-4-times: sext\\.
+ * check-output-pattern-12-times: trunc\\.4
* check-output-pattern-6-times: lsr\\..*\\$6
*/
diff --git a/validation/builtin-bswap-variable.c b/validation/builtin-bswap-variable.c
index 738ba2a45..40ad64134 100644
--- a/validation/builtin-bswap-variable.c
+++ b/validation/builtin-bswap-variable.c
@@ -25,8 +25,8 @@ static u64 swap64v(u32 a)
*
* check-output-ignore
* check-output-contains:call.16 .* __builtin_bswap16
- * check-output-contains:cast.32 .* (64) %arg1
+ * check-output-contains:trunc.32 .* (64) %arg1
* check-output-contains:call.32 .* __builtin_bswap32
- * check-output-contains:cast.64 .* (32) %arg1
+ * check-output-contains:zext.64 .* (32) %arg1
* check-output-contains:call.64 .* __builtin_bswap64
*/
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index fe0f83e24..4654dbda2 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -13,11 +13,6 @@ cast-kinds.c:12:48: warning: cast drops bits
cast-kinds.c:13:50: warning: cast drops bits
cast-kinds.c:14:49: warning: cast drops bits
cast-kinds.c:15:48: warning: cast drops bits
-cast-kinds.c:21:49: warning: cast wasn't removed
-cast-kinds.c:28:52: warning: cast wasn't removed
-cast-kinds.c:34:52: warning: cast wasn't removed
-cast-kinds.c:35:54: warning: cast wasn't removed
-cast-kinds.c:36:52: warning: cast wasn't removed
cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast
cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast
* check-error-end
diff --git a/validation/cast-kinds.c b/validation/cast-kinds.c
index 3ac95c3dc..7d977f91b 100644
--- a/validation/cast-kinds.c
+++ b/validation/cast-kinds.c
@@ -74,44 +74,44 @@ uint_2_int:
long_2_int:
.L2:
<entry-point>
- scast.32 %r5 <- (64) %arg1
- ret.32 %r5
+ trunc.32 %r4 <- (64) %arg1
+ ret.32 %r4
ulong_2_int:
.L4:
<entry-point>
- cast.32 %r8 <- (64) %arg1
- ret.32 %r8
+ trunc.32 %r7 <- (64) %arg1
+ ret.32 %r7
vptr_2_int:
.L6:
<entry-point>
- cast.32 %r11 <- (64) %arg1
- ret.32 %r11
+ trunc.32 %r10 <- (64) %arg1
+ ret.32 %r10
iptr_2_int:
.L8:
<entry-point>
- ptrtu.64 %r14 <- (64) %arg1
- cast.32 %r15 <- (64) %r14
- ret.32 %r15
+ ptrtu.64 %r13 <- (64) %arg1
+ trunc.32 %r14 <- (64) %r13
+ ret.32 %r14
float_2_int:
.L10:
<entry-point>
- fcvts.32 %r18 <- (32) %arg1
- ret.32 %r18
+ fcvts.32 %r17 <- (32) %arg1
+ ret.32 %r17
double_2_int:
.L12:
<entry-point>
- fcvts.32 %r21 <- (64) %arg1
- ret.32 %r21
+ fcvts.32 %r20 <- (64) %arg1
+ ret.32 %r20
int_2_uint:
@@ -123,58 +123,58 @@ int_2_uint:
long_2_uint:
.L16:
<entry-point>
- scast.32 %r27 <- (64) %arg1
- ret.32 %r27
+ trunc.32 %r25 <- (64) %arg1
+ ret.32 %r25
ulong_2_uint:
.L18:
<entry-point>
- cast.32 %r30 <- (64) %arg1
- ret.32 %r30
+ trunc.32 %r28 <- (64) %arg1
+ ret.32 %r28
vptr_2_uint:
.L20:
<entry-point>
- cast.32 %r33 <- (64) %arg1
- ret.32 %r33
+ trunc.32 %r31 <- (64) %arg1
+ ret.32 %r31
iptr_2_uint:
.L22:
<entry-point>
- ptrtu.64 %r36 <- (64) %arg1
- cast.32 %r37 <- (64) %r36
- ret.32 %r37
+ ptrtu.64 %r34 <- (64) %arg1
+ trunc.32 %r35 <- (64) %r34
+ ret.32 %r35
float_2_uint:
.L24:
<entry-point>
- fcvtu.32 %r40 <- (32) %arg1
- ret.32 %r40
+ fcvtu.32 %r38 <- (32) %arg1
+ ret.32 %r38
double_2_uint:
.L26:
<entry-point>
- fcvtu.32 %r43 <- (64) %arg1
- ret.32 %r43
+ fcvtu.32 %r41 <- (64) %arg1
+ ret.32 %r41
int_2_long:
.L28:
<entry-point>
- scast.64 %r46 <- (32) %arg1
- ret.64 %r46
+ sext.64 %r44 <- (32) %arg1
+ ret.64 %r44
uint_2_long:
.L30:
<entry-point>
- cast.64 %r49 <- (32) %arg1
- ret.64 %r49
+ zext.64 %r47 <- (32) %arg1
+ ret.64 %r47
ulong_2_long:
@@ -186,43 +186,42 @@ ulong_2_long:
vptr_2_long:
.L34:
<entry-point>
- cast.64 %r55 <- (64) %arg1
- ret.64 %r55
+ ret.64 %arg1
iptr_2_long:
.L36:
<entry-point>
- ptrtu.64 %r58 <- (64) %arg1
- ret.64 %r58
+ ptrtu.64 %r54 <- (64) %arg1
+ ret.64 %r54
float_2_long:
.L38:
<entry-point>
- fcvts.64 %r61 <- (32) %arg1
- ret.64 %r61
+ fcvts.64 %r57 <- (32) %arg1
+ ret.64 %r57
double_2_long:
.L40:
<entry-point>
- fcvts.64 %r64 <- (64) %arg1
- ret.64 %r64
+ fcvts.64 %r60 <- (64) %arg1
+ ret.64 %r60
int_2_ulong:
.L42:
<entry-point>
- scast.64 %r67 <- (32) %arg1
- ret.64 %r67
+ sext.64 %r63 <- (32) %arg1
+ ret.64 %r63
uint_2_ulong:
.L44:
<entry-point>
- cast.64 %r70 <- (32) %arg1
- ret.64 %r70
+ zext.64 %r66 <- (32) %arg1
+ ret.64 %r66
long_2_ulong:
@@ -234,171 +233,167 @@ long_2_ulong:
vptr_2_ulong:
.L48:
<entry-point>
- cast.64 %r76 <- (64) %arg1
- ret.64 %r76
+ ret.64 %arg1
iptr_2_ulong:
.L50:
<entry-point>
- ptrtu.64 %r79 <- (64) %arg1
- ret.64 %r79
+ ptrtu.64 %r73 <- (64) %arg1
+ ret.64 %r73
float_2_ulong:
.L52:
<entry-point>
- fcvtu.64 %r82 <- (32) %arg1
- ret.64 %r82
+ fcvtu.64 %r76 <- (32) %arg1
+ ret.64 %r76
double_2_ulong:
.L54:
<entry-point>
- fcvtu.64 %r85 <- (64) %arg1
- ret.64 %r85
+ fcvtu.64 %r79 <- (64) %arg1
+ ret.64 %r79
int_2_vptr:
.L56:
<entry-point>
- scast.64 %r88 <- (32) %arg1
- ret.64 %r88
+ sext.64 %r82 <- (32) %arg1
+ ret.64 %r82
uint_2_vptr:
.L58:
<entry-point>
- cast.64 %r91 <- (32) %arg1
- ret.64 %r91
+ zext.64 %r85 <- (32) %arg1
+ ret.64 %r85
long_2_vptr:
.L60:
<entry-point>
- scast.64 %r94 <- (64) %arg1
- ret.64 %r94
+ ret.64 %arg1
ulong_2_vptr:
.L62:
<entry-point>
- cast.64 %r97 <- (64) %arg1
- ret.64 %r97
+ ret.64 %arg1
iptr_2_vptr:
.L64:
<entry-point>
- cast.64 %r100 <- (64) %arg1
- ret.64 %r100
+ ret.64 %arg1
int_2_iptr:
.L66:
<entry-point>
- scast.64 %r103 <- (32) %arg1
- utptr.64 %r104 <- (64) %r103
- ret.64 %r104
+ sext.64 %r94 <- (32) %arg1
+ utptr.64 %r95 <- (64) %r94
+ ret.64 %r95
uint_2_iptr:
.L68:
<entry-point>
- cast.64 %r107 <- (32) %arg1
- utptr.64 %r108 <- (64) %r107
- ret.64 %r108
+ zext.64 %r98 <- (32) %arg1
+ utptr.64 %r99 <- (64) %r98
+ ret.64 %r99
long_2_iptr:
.L70:
<entry-point>
- utptr.64 %r111 <- (64) %arg1
- ret.64 %r111
+ utptr.64 %r102 <- (64) %arg1
+ ret.64 %r102
ulong_2_iptr:
.L72:
<entry-point>
- utptr.64 %r114 <- (64) %arg1
- ret.64 %r114
+ utptr.64 %r105 <- (64) %arg1
+ ret.64 %r105
vptr_2_iptr:
.L74:
<entry-point>
- ptrcast.64 %r117 <- (64) %arg1
- ret.64 %r117
+ ptrcast.64 %r108 <- (64) %arg1
+ ret.64 %r108
int_2_float:
.L76:
<entry-point>
- scvtf.32 %r120 <- (32) %arg1
- ret.32 %r120
+ scvtf.32 %r111 <- (32) %arg1
+ ret.32 %r111
uint_2_float:
.L78:
<entry-point>
- ucvtf.32 %r123 <- (32) %arg1
- ret.32 %r123
+ ucvtf.32 %r114 <- (32) %arg1
+ ret.32 %r114
long_2_float:
.L80:
<entry-point>
- scvtf.32 %r126 <- (64) %arg1
- ret.32 %r126
+ scvtf.32 %r117 <- (64) %arg1
+ ret.32 %r117
ulong_2_float:
.L82:
<entry-point>
- ucvtf.32 %r129 <- (64) %arg1
- ret.32 %r129
+ ucvtf.32 %r120 <- (64) %arg1
+ ret.32 %r120
double_2_float:
.L84:
<entry-point>
- fcvtf.32 %r132 <- (64) %arg1
- ret.32 %r132
+ fcvtf.32 %r123 <- (64) %arg1
+ ret.32 %r123
int_2_double:
.L86:
<entry-point>
- scvtf.64 %r135 <- (32) %arg1
- ret.64 %r135
+ scvtf.64 %r126 <- (32) %arg1
+ ret.64 %r126
uint_2_double:
.L88:
<entry-point>
- ucvtf.64 %r138 <- (32) %arg1
- ret.64 %r138
+ ucvtf.64 %r129 <- (32) %arg1
+ ret.64 %r129
long_2_double:
.L90:
<entry-point>
- scvtf.64 %r141 <- (64) %arg1
- ret.64 %r141
+ scvtf.64 %r132 <- (64) %arg1
+ ret.64 %r132
ulong_2_double:
.L92:
<entry-point>
- ucvtf.64 %r144 <- (64) %arg1
- ret.64 %r144
+ ucvtf.64 %r135 <- (64) %arg1
+ ret.64 %r135
float_2_double:
.L94:
<entry-point>
- fcvtf.64 %r147 <- (32) %arg1
- ret.64 %r147
+ fcvtf.64 %r138 <- (32) %arg1
+ ret.64 %r138
float_2_float:
diff --git a/validation/cast-weirds.c b/validation/cast-weirds.c
index 71e52ff57..a99c65d25 100644
--- a/validation/cast-weirds.c
+++ b/validation/cast-weirds.c
@@ -20,7 +20,7 @@ cast-weirds.c:5:44: warning: non size-preserving integer to pointer cast
int_2_iptr:
.L0:
<entry-point>
- scast.64 %r2 <- (32) %arg1
+ sext.64 %r2 <- (32) %arg1
utptr.64 %r3 <- (64) %r2
ret.64 %r3
@@ -28,7 +28,7 @@ int_2_iptr:
uint_2_iptr:
.L2:
<entry-point>
- cast.64 %r6 <- (32) %arg1
+ zext.64 %r6 <- (32) %arg1
utptr.64 %r7 <- (64) %r6
ret.64 %r7
@@ -36,14 +36,14 @@ uint_2_iptr:
int_2_vptr:
.L4:
<entry-point>
- scast.64 %r10 <- (32) %arg1
+ sext.64 %r10 <- (32) %arg1
ret.64 %r10
uint_2_vptr:
.L6:
<entry-point>
- cast.64 %r13 <- (32) %arg1
+ zext.64 %r13 <- (32) %arg1
ret.64 %r13
diff --git a/validation/compound-assign-type.c b/validation/compound-assign-type.c
index 450fa26d9..e13dcfcd2 100644
--- a/validation/compound-assign-type.c
+++ b/validation/compound-assign-type.c
@@ -11,5 +11,6 @@ static unsigned int foo(unsigned int x, long a)
*
* check-output-excludes: divu\\.32
* check-output-contains: divs\\.64
- * check-output-contains: scast\\.32
+ * check-output-contains: zext.64 .* (32) %arg1
+ * check-output-contains: trunc.32 .* (64)
*/
diff --git a/validation/linear/bitfield-init-zero.c b/validation/linear/bitfield-init-zero.c
index 39a64345e..7a410a7c4 100644
--- a/validation/linear/bitfield-init-zero.c
+++ b/validation/linear/bitfield-init-zero.c
@@ -57,7 +57,7 @@ int bfs_get0(void)
bfuu_init:
.L0:
<entry-point>
- cast.9 %r2 <- (32) %arg1
+ trunc.9 %r2 <- (32) %arg1
shl.32 %r4 <- %r2, $11
ret.32 %r4
@@ -65,7 +65,7 @@ bfuu_init:
bfus_init:
.L2:
<entry-point>
- scast.9 %r10 <- (32) %arg1
+ trunc.9 %r10 <- (32) %arg1
shl.32 %r12 <- %r10, $11
ret.32 %r12
@@ -79,7 +79,7 @@ bfu_get0:
bfsu_init:
.L6:
<entry-point>
- cast.9 %r23 <- (32) %arg1
+ trunc.9 %r23 <- (32) %arg1
shl.32 %r25 <- %r23, $11
ret.32 %r25
@@ -87,7 +87,7 @@ bfsu_init:
bfss_init:
.L8:
<entry-point>
- scast.9 %r31 <- (32) %arg1
+ trunc.9 %r31 <- (32) %arg1
shl.32 %r33 <- %r31, $11
ret.32 %r33
diff --git a/validation/memops-volatile.c b/validation/memops-volatile.c
index 0f3e12ad2..3b8662f1e 100644
--- a/validation/memops-volatile.c
+++ b/validation/memops-volatile.c
@@ -13,8 +13,8 @@ foo:
.L0:
<entry-point>
store.32 %arg2 -> 0[%arg1]
- load.32 %r5 <- 0[%arg1]
- ret.32 %r5
+ load.32 %r4 <- 0[%arg1]
+ ret.32 %r4
* check-output-end
diff --git a/validation/optim/bool-simplify.c b/validation/optim/bool-simplify.c
index 05be11497..5b3cf449e 100644
--- a/validation/optim/bool-simplify.c
+++ b/validation/optim/bool-simplify.c
@@ -33,7 +33,7 @@ and_1:
.L2:
<entry-point>
setne.1 %r8 <- %arg1, $0
- cast.32 %r11 <- (1) %r8
+ zext.32 %r11 <- (1) %r8
ret.32 %r11
@@ -41,7 +41,7 @@ or_0:
.L4:
<entry-point>
setne.1 %r14 <- %arg1, $0
- cast.32 %r17 <- (1) %r14
+ zext.32 %r17 <- (1) %r14
ret.32 %r17
--
2.14.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 01/14] add documentation for IR instructions
2017-08-17 4:05 ` [RFC PATCH 01/14] add documentation for IR instructions Luc Van Oostenryck
@ 2017-08-21 12:18 ` Christopher Li
0 siblings, 0 replies; 16+ messages in thread
From: Christopher Li @ 2017-08-21 12:18 UTC (permalink / raw)
To: Luc Van Oostenryck; +Cc: Linux-Sparse, Linus Torvalds, Dibyendu Majumdar
On Thu, Aug 17, 2017 at 12:05 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> Until now the 'instructions' used for spare's IR are
> not at all documented.
>
> This patch is a fist step toward having these instructions
> properly documented.
Yes, the sparse doucment is lacking.
This is great.
Thanks you.
Chris
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2017-08-21 12:18 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-17 4:05 [RFC PATCH 00/14] rework of cast operations Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 01/14] add documentation for IR instructions Luc Van Oostenryck
2017-08-21 12:18 ` Christopher Li
2017-08-17 4:05 ` [RFC PATCH 02/14] cast: add tests for warnings issued by sparse -v Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 03/14] cast: prepare finer grained cast instructions Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 04/14] cast: specialize FPCAST into [USF]CVTF Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 05/14] cast: handle NO-OP casts Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 06/14] cast: specialize floats to integer conversion Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 07/14] cast: specialize casts from unsigned to pointers Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 08/14] cast: make [u]intptr_ctype alias of [s]size_t_ctype Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 09/14] cast: make pointer casts always size preserving Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 10/14] cast: temporary simplify handling cast to/from void* Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 11/14] cast: specialize cast from pointers Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 12/14] cast: add support for -Wpointer-to-int-cast Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 13/14] cast: make casts from pointer always size preserving Luc Van Oostenryck
2017-08-17 4:05 ` [RFC PATCH 14/14] cast: specialize integer casts Luc Van Oostenryck
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).