This is an archive of the discontinued LLVM Phabricator instance.

[DAG]: Combine multiple AssertZexts separated by trunc
Needs ReviewPublic

Authored by hans on Mar 8 2016, 3:59 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

(Uploading as a work-in-progress in case anyone wants to comment.)

The two AssertZexts situation arises for boolean arguments on X86_64:

void f(bool x) {

LLVM will copy x from a 32-bit register, insert an AssertZext to capture that bits 8-31 are zero (as byte-sized arguments get extended on x86_64), and then another AssertZext to capture that bits 1-7 are also zero, because that's true for bools.

Combining the two allows us to optimize this code:

void g(bool);
void f(bool x) {
  g(x);
}

Previously:

movzbl  %dil, %edi
jmp     _Z1gb

After my patch, no zero-extension is generated, as the value in %edi was already extended by the caller.

This raises a number of questions, though:

  1. Are 8- and 16-bit arguments really extended on x86_64? LLVM assumes so since http://reviews.llvm.org/rL34623, but the psABI doesn't seem to actually spell that out?
  1. Are bools really extended to 32 bits on x86_64? http://reviews.llvm.org/rL127766 says they are not and "[...] We still insert an i32 ZextAssert when reading a function's arguments, but it is followed by a truncate and another i8 ZextAssert so it is not optimized." The psABI seems to have gone back and forth here(!).

My patch would break Win64, because there it's clear that a bool argument is extended only to 8 bits, not 32 bits. But from what I understand, this isn't represented well: Clang's WinX86_64ABIInfo::classify will slap a "zext" attribute on the x parameter, and we end up with both AssertZexts.

Diff Detail

Event Timeline

hans updated this revision to Diff 50078.Mar 8 2016, 3:59 PM
hans retitled this revision from to [DAG]: Combine multiple AssertZexts separated by trunc.
hans updated this object.
hans added subscribers: rnk, llvm-commits.