Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Optimization bug compiling for ARM v7a (32-bit) #43609

Open Quuxplusone opened 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR44639
Status NEW
Importance P release blocker
Reported by Brian Palmer (brianp@dashlogic.com)
Reported on 2020-01-23 10:27:55 -0800
Last modified on 2020-01-23 16:21:38 -0800
Version 8.0
Hardware PC All
CC blitzrakete@gmail.com, dgregor@apple.com, efriedma@quicinc.com, erik.pilkington@gmail.com, htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, ndesaulniers@google.com, richard-llvm@metafoo.co.uk, srhines@google.com
Fixed by commit(s)
Attachments ClangBugTest.zip (248512 bytes, application/x-zip-compressed)
Blocks
Blocked by
See also
Created attachment 23048
Android Studio example project

My development environment is using Windows 10, Android Studio v3.5.3, Android
NDK v20.0.5594570, with Clang v8.0.7. This bug appears to only happen when
targeting armeabi-v7a for 32-bit Android, and not for arm64-v8a or any x86
variant.

While working with the pixman graphics library compiling for Android, we've
found a bug when optimizations are turned off using #pragma optimize off during
a release variant build of the app. The exact error message is:

[armeabi-v7a] Compile arm    : myappnative <= android.c
fatal error: error in backend: symbol '.LPC5_0' can not be undefined in a
subtraction expression

I've pulled some snippets of source out of the pixman library into an example
project that reproduces this error (attached).

In the attached example project, in the file android.c, the error happens on
line 144 and line 174, as follows (line 144 shown):

src_flags = narrow | op_flags[op].src;

If replaced with src_flags = 0, the error goes away. The error also gets
resolved if #pragma optimize is removed, or if compiled as a debug build.

I don't understand the LLVM/Clang code well enough to know for sure, but in
researching this bug I came across the following possibly related bugs:
https://bugs.llvm.org/show_bug.cgi?id=7334
https://bugs.llvm.org/show_bug.cgi?id=7353
https://bugs.llvm.org/show_bug.cgi?id=10992
Quuxplusone commented 4 years ago

Attached ClangBugTest.zip (248512 bytes, application/x-zip-compressed): Android Studio example project

Quuxplusone commented 4 years ago

Casting a literal to an enum type that doesn't have an enumeration value that matches is unspecified behavior in C, and explicitly UB in C++20.

src_flags is defined in android.c as:

iter_flags_t narrow, src_flags;

iter_flags_t is defined in android.h as:

typedef enum { ITER_NARROW = (1 << 0), ITER_LOCALIZED_ALPHA = (1 << 1), ITER_IGNORE_ALPHA = (1 << 2), ITER_IGNORE_RGB = (1 << 3) } iter_flags_t;

So the value 0 is not a valid iter_flags_t.

general_composite_rect() has a conditional that may assign 0 to narrow, which is then used to assign a value to src_flags.

See also: https://wiki.sei.cmu.edu/confluence/display/cplusplus/INT50-CPP.+Do+not+cast+to+an+out-of-range+enumeration+value

That looks fishy, but I haven't been able to come up with a smaller reproducer.

Quuxplusone commented 4 years ago
(In reply to Nick Desaulniers from comment #1)
> Casting a literal to an enum type that doesn't have an enumeration value
> that matches is unspecified behavior in C, and explicitly UB in C++20.

The C++ rule here is a bit looser than what you're describing: "the values of
the enumeration are the values representable by a hypothetical integer type
with minimal width M such that all enumerators can be represented".  So it's
always okay to convert 0 to an enum type.

In any case, even if the code did have undefined behavior, that shouldn't lead
to a compile error.