[PATCH 08/20] cast: specialize FPCAST into [USF]CVTF

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

 



Currently, all casts to a floating point type use OP_FPCAST.
This is maybe simple but rather uncovenient as it correspond
to several quite different operations that later need extra
checks.

Change this by directly using different instructions for the
different cases:
- 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@xxxxxxxxx>
---
 Documentation/IR.rst           | 12 +++++++++---
 example.c                      |  8 ++++++--
 linearize.c                    | 18 +++++++++++++++---
 linearize.h                    |  3 ++-
 liveness.c                     |  3 ++-
 simplify.c                     | 11 +++++++----
 sparse-llvm.c                  | 16 ++++++++++++----
 validation/linear/cast-kinds.c | 20 ++++++++++----------
 8 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/Documentation/IR.rst b/Documentation/IR.rst
index 67ef06a5d..38683a73b 100644
--- a/Documentation/IR.rst
+++ b/Documentation/IR.rst
@@ -270,12 +270,18 @@ They all have the following signature:
 .. op:: OP_SCAST
 	Cast to signed integer.
 
-.. op:: OP_FPCAST
-	Cast to floating-point.
-
 .. op:: OP_PTRCAST
 	Cast to pointer.
 
+.. op:: OP_UCVTF
+	Conversion from unsigned integer to float type.
+
+.. op:: OP_SCVTF
+	Conversion from signed integer to float type.
+
+.. op:: OP_FCVTF
+	Conversion between float types.
+
 Ternary ops
 -----------
 .. op:: OP_SEL
diff --git a/example.c b/example.c
index fd22d8ab2..23b941e7a 100644
--- a/example.c
+++ b/example.c
@@ -76,7 +76,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_SLICE] = "slice",
@@ -1409,7 +1411,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 cb6449a61..c6c377b2e 100644
--- a/linearize.c
+++ b/linearize.c
@@ -263,7 +263,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",
@@ -445,7 +447,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),
@@ -1201,7 +1204,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 db4a67f3d..2900b5cae 100644
--- a/linearize.h
+++ b/linearize.h
@@ -234,7 +234,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 e0e583292..362b8a413 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 be7208608..fe23741fb 100644
--- a/simplify.c
+++ b/simplify.c
@@ -253,7 +253,8 @@ int 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:
@@ -354,7 +355,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;
@@ -988,7 +990,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;
 	}
 
@@ -1223,7 +1225,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 b22d2f67b..4919305b5 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -944,12 +944,19 @@ static void output_op_fpcast(struct function *fn, struct instruction *insn)
 
 	pseudo_name(insn->target, name);
 	src = get_operand(fn, otype, insn->src);
-	if (is_float_type(otype))
+	switch (insn->opcode) {
+	case OP_FCVTF:
 		target = LLVMBuildFPCast(fn->builder, src, dtype, name);
-	else if (is_signed_type(otype))
+		break;
+	case OP_SCVTF:
 		target = LLVMBuildSIToFP(fn->builder, src, dtype, name);
-	else
+		break;
+	case OP_UCVTF:
 		target = LLVMBuildUIToFP(fn->builder, src, dtype, name);
+		break;
+	default:
+		assert(0);
+	}
 	insn->target->priv = target;
 }
 
@@ -1028,7 +1035,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:
 		output_op_fpcast(fn, insn);
 		break;
 	case OP_PTRCAST:
diff --git a/validation/linear/cast-kinds.c b/validation/linear/cast-kinds.c
index e686c01ea..d8ac5d34f 100644
--- a/validation/linear/cast-kinds.c
+++ b/validation/linear/cast-kinds.c
@@ -320,70 +320,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.17.1

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

  Powered by Linux