fptosi/fptoui must convert (-1.0, -0.0) to 0, not poison
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -1259,15 +1259,18 @@ StateValue ConversionOp::toSMT(State &s) const {
fn = [](auto &&val, auto &to_type) -> StateValue {
expr bv = val.fp2sint(to_type.bits());
expr fp2 = bv.sint2fp(val);
- // -0.0 is converted to 0 and then to 0.0, though -0.0 is ok to convert
- return { move(bv), val.isFPZero() || fp2 == val.roundtz() };
+ // -0.xx is converted to 0 and then to 0.0, though -0.xx is ok to convert
+ expr valrtz = val.roundtz();
+ return { move(bv), valrtz.isFPZero() || fp2 == valrtz };
};
break;
case FPToUInt:
fn = [](auto &&val, auto &to_type) -> StateValue {
expr bv = val.fp2uint(to_type.bits());
expr fp2 = bv.uint2fp(val);
- return { move(bv), fp2 == val.roundtz() };
+ // -0.xx must be converted to 0, not poison.
+ expr valrtz = val.roundtz();
+ return { move(bv), valrtz.isFPZero() || fp2 == valrtz };
};
break;
case FPExt:

ADD
tests/alive-tv/fp/D113543-fptosi.srctgt.ll
+define i16 @src() {
+ ret i16 0
+}
+
+define i16 @tgt() {
+ %a = fptosi half -0.25 to i16
+ ret i16 %a
+}

ADD
tests/alive-tv/fp/D113543-fptoui.srctgt.ll
+define i16 @src() {
+ ret i16 0
+}
+
+define i16 @tgt() {
+ %a = fptoui half -0.25 to i16
+ ret i16 %a
+}

fptosi/fptoui must convert (-1.0, -0.0) to 0, not poison (#767)