@@ -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.
@@ -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);
@@ -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:
@@ -198,6 +198,7 @@ enum opcode {
OP_PHISOURCE,
OP_CAST,
OP_SCAST,
+ OP_FCVTU, OP_FCVTS,
OP_UCVTF, OP_SCVTF,
OP_FCVTF,
OP_PTRCAST,
@@ -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:
@@ -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:
@@ -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);
@@ -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
@@ -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:
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(-)