This is an archive of the discontinued LLVM Phabricator instance.

[mips] Sign-extend i32 values truncated from previously zero-extended i32 values.
ClosedPublic

Authored by vkalintiris on Apr 8 2016, 2:44 AM.

Details

Summary

This is a special case for MIPS64 because the architecture requires
properly 32-bit sign-extended values in the register containers.

Additionaly, we merge consecutive trunc + AssertZExt nodes in order
to avoid unnecessary sign-extensions when the extension comes from a
type smaller than i32.

Diff Detail

Repository
rL LLVM

Event Timeline

vkalintiris updated this revision to Diff 53008.Apr 8 2016, 2:44 AM
vkalintiris retitled this revision from to [mips] Sign-extend i32 values truncated from previously zero-extended i32 values..
vkalintiris updated this object.
vkalintiris added a reviewer: dsanders.
vkalintiris added a subscriber: llvm-commits.

Avoid C++ DAG-to-DAG transformations by using tablegen's PatFrag for AssertZexts widening from types less than i32.

dsanders added inline comments.Apr 12 2016, 11:17 AM
lib/Target/Mips/Mips64InstrInfo.td
516 ↗(On Diff #53390)

Could you add a comment explaining why this isn't valid for the i32 case?

lib/Target/Mips/MipsISelLowering.cpp
823 ↗(On Diff #53390)

Some closing parenthesis are missing on the LHS.

823–827 ↗(On Diff #53390)

The code implements the right behaviour but I think the expressions in the comment may be inside-out and the usage of 'outer' and 'inner' are the opposite way around to what I'd expect ('outer' is used for N->getOperand(0)->getOperand(0)). Shouldn't the first expression be?:

(AssertZext:i32 (trunc:i32 (AssertZext:i64 X, i32)), i8)
  -> (trunc:i32 (AssertZext X, i8))

Also, I don't think the test cases cover this dag combine rule at the moment. assertzext-trunc.ll doesn't trigger the assertzext/trunc/assertzext case we've looked at before. divrem.ll and octeon_popcnt.ll used to trigger it but don't anymore because of the change to make the arguments signext.

vkalintiris marked 3 inline comments as done.

Use wider/narrower semantics for nested AssertZext nodes and add a new test case.

lib/Target/Mips/MipsISelLowering.cpp
823–827 ↗(On Diff #53390)

Shouldn't the first expression be?:

(AssertZext:i32 (trunc:i32 (AssertZext:i64 X, i32)), i8)

-> (trunc:i32 (AssertZext X, i8))

That's correct, I swapped the VTs accidentally.

Also, I don't think the test cases cover this dag combine rule at the moment.

It's covered (albeit implicitly) by llvm-ir/{udiv,lshr}.ll and mips64-f128.ll. I copied the IR that triggers this behaviour from llvm-ir/udiv.ll to assertzext-trunc.ll.

dsanders accepted this revision.Apr 13 2016, 6:34 AM
dsanders edited edge metadata.

LGTM with a change to the new comment.

lib/Target/Mips/Mips64InstrInfo.td
516 ↗(On Diff #53526)

We need to be explicit about what it means to be 'properly sign-extended' since the correct behaviour is likely to be counter-intuitive to most readers. If you were to ask what the register representation of the uint32_t value 0x80000000 is on a 64-bit MIPS, I doubt many people would answer 0xFFFFFFFF80000000.

This revision is now accepted and ready to land.Apr 13 2016, 6:34 AM
This revision was automatically updated to reflect the committed changes.