Use sign-extension for all W32 branch comparisons

ce3e5c399d9462245c5936c3dbdace623df87de8f9bd94333b02fd575a7c6b49
Alexis Sellier committed ago 1 parent da5a5cd5
lib/std/arch/rv64/isel.rad +8 -5
547 547
            // For SLT: sign-extension needed (signed comparison).
548 548
            // For ULT: zero-extension needed (unsigned magnitude comparison).
549 549
            // For EQ/NE with W32: sign-extension is cheaper.
550 550
            // For EQ/NE with W8/W16: keep zero-extension.
551 551
            // Skip extension for zero register.
552 -
            if let case il::CmpOp::Slt = op {
552 +
            if typ == il::Type::W32 {
553 +
                // Sign-extension suffices for *all* comparison types on RV64.
554 +
                // For SLT: sign-extension is semantically correct.
555 +
                // For ULT: bltu gives identical results on sign- vs zero-
556 +
                // extended W32 values (the relative ordering is preserved
557 +
                // because the sign bit maps to the same half of 64-bit space).
558 +
                // For EQ/NE: both extensions produce identical equality results.
553 559
                if not aIsZero { emitSext(s.e, rs1, rs1, typ); }
554 560
                if not bIsZero { emitSext(s.e, rs2, rs2, typ); }
555 -
            } else if let case il::CmpOp::Ult = op {
556 -
                if not aIsZero { emitZext(s.e, rs1, rs1, typ); }
557 -
                if not bIsZero { emitZext(s.e, rs2, rs2, typ); }
558 -
            } else if typ == il::Type::W32 {
561 +
            } else if let case il::CmpOp::Slt = op {
559 562
                if not aIsZero { emitSext(s.e, rs1, rs1, typ); }
560 563
                if not bIsZero { emitSext(s.e, rs2, rs2, typ); }
561 564
            } else {
562 565
                if not aIsZero { emitZext(s.e, rs1, rs1, typ); }
563 566
                if not bIsZero { emitZext(s.e, rs2, rs2, typ); }