char shortened to i1


I have a C module which looks something like this:
static char status = 0;
char StatusFunc() { return status; }
void AnotherFunc() { status = -1; }

Once Clang is finished with this module it gives the following IR:
@status = internal unnamed_addr global i1 false
define StatusFunc ... {
  %.b = load i1* @status, align 1
  %1 = sext i1 %.b to i8
  ret i8 %1

The important thing here is that the static variable has been
shortened to i1. If I change AnotherFunc to set status = -2 instead
this isn't done.

When I look at the generated code for a couple of different targets
(e.g. x86_64) the common principle seem to be that the value is
loaded, extended and returned in StatusFunc. Using i8 for the type
simplifies this as the extension isn't needed.

Which Clang optimization performs this change?
In this particular situation it seems to me that the optimization will
hurt performance and program size but help reduce memory usage. Are
there other situations where it is more of a win-win?

Would it be legal for a backend to expand the i1 to i8?

I'm grateful for any information on this subject.

- David

After some more investigation it seems like it is the LLVM globalopt
pass which performs this optimization and the code describes its area
of usage quite good.

Sorry for the noise.

- David