Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang should reject mode(TI) on 32-bit targets #5022

Open Quuxplusone opened 14 years ago

Quuxplusone commented 14 years ago
Bugzilla Link PR7428
Status NEW
Importance P normal
Reported by Jan Seiffert (kaffeemonster@googlemail.com)
Reported on 2010-06-20 13:07:18 -0700
Last modified on 2013-05-13 17:30:44 -0700
Version trunk
Hardware PC Linux
CC baldrick@free.fr, clattner@nondot.org, kremenek@apple.com, llvm-bugs@lists.llvm.org, llvm@sunfishcode.online
Fixed by commit(s)
Attachments bugpoint-reduced-simplified.bc (588 bytes, application/octet-stream)
test5.c (201 bytes, text/x-csrc)
Blocks
Blocked by
See also
Created attachment 5064
bugpoint reduced problem

Build myself a fresh clang today TOT@106404.

Compiling my source i got this:

$ clang -DHAVE_CONFIG_H -O2 -pthread -c lib/vsnprintf.c -o lib/vsnprintf.o
UNREACHABLE executed!
Stack dump:
0.      Program arguments: /usr/bin/clang -cc1 -triple i386-pc-linux-gnu -S -
disable-free -disable-llvm-verifier -main-file-name vsnprintf.c -mrelocation-
model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -
resource-dir /usr/lib/clang/2.0 -D HAVE_CONFIG_H -O2 -ferror-limit 19 -fmessage-
length 114 -pthread -fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics
-o /tmp/cc-SHeyFV.s -x c lib/vsnprintf.c
1.      <eof> parser at end of file
2.      Code generation
3.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@vdtoa'
clang: error: clang frontend command failed due to signal 6 (use -v to see
invocation)

The reason seems to be, that my configure script detects that clang supports
__attribute__((mode(TI))), even on 32 bit. If this happens some code uses it to
do 64Bit arithmetic with overflow. An example:
#define MUL_BIG(x, y, z, k) \
{ \
    __uint128 a_res = (__uint128)(x) * (y) + (k); \
    (k) = a_res >> 64; \
    (z) = a_res; \
}

IMHO there is no reason the compiler should not handle this on 32 Bit (if i
lower it or the compiler does it, but i think the compiler can do a better job
than me clumsily describing the same thing in C).

bugpoint reduced .ll:

; ModuleID = 'bugpoint-reduced-simplified.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-
f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"

define void @vdtoa() nounwind {
  br i1 undef, label %._crit_edge431, label %add_cmp.exit152

._crit_edge431:                                   ; preds = %bb.nph.i154, %0
  ret void

add_cmp.exit152:                                  ; preds = %0
  %1 = icmp sgt i32 undef, -1                     ; <i1> [#uses=1]
  br i1 %1, label %bb.nph.i154, label %mul10.exit162

bb.nph.i154:                                      ; preds = %bb.nph.i154,
%add_cmp.exit152
  %2 = zext i64 undef to i128                     ; <i128> [#uses=0]
  br i1 undef, label %._crit_edge431, label %bb.nph.i154

mul10.exit162:                                    ; preds = %add_cmp.exit152
  br i1 undef, label %bb.nph.i188, label %bb.nph.i

bb.nph.i188:                                      ; preds = %bb.nph.i188,
%mul10.exit162
  br label %bb.nph.i188

bb.nph.i:                                         ; preds = %bb.nph.i,
%mul10.exit162
  br label %bb.nph.i
}

Hmmm, and from a peek at it, and what i understand of ll (nothing...) the only
i128 is the zero extention from i64, the rest is IMHO just fluff.
I will attach the .bc, you guys are the gurus.

Greetings
Jan
Quuxplusone commented 14 years ago

Attached bugpoint-reduced-simplified.bc (588 bytes, application/octet-stream): bugpoint reduced problem

Quuxplusone commented 14 years ago
Ping?
Can someone at least reproduce?
Still seeing it with TOT@107143.
Should i add a testcase in C?

Greetings
Jan
Quuxplusone commented 14 years ago
(In reply to comment #1)
> Ping?
> Can someone at least reproduce?
> Still seeing it with TOT@107143.
> Should i add a testcase in C?
>
> Greetings
> Jan

Yes, please add a test case so we can reproduce at the frontend level.  This is
likely a backend bug, but being able to generate the .ll file directly from a
.c file is handy.
Quuxplusone commented 14 years ago

Attached test5.c (201 bytes, text/x-csrc): testcase in C

Quuxplusone commented 14 years ago
Here is a reduced testcase:

target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-
f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
target triple = "i386-apple-darwin10.0.0"

define void @MUL_BIG() nounwind ssp {
entry:
  %conv = zext i64 undef to i128                  ; <i128> [#uses=1]
  %conv2 = zext i64 undef to i128                 ; <i128> [#uses=1]
  %mul = mul i128 %conv, %conv2                   ; <i128> [#uses=1]
  %add = add i128 %mul, 0                         ; <i128> [#uses=1]
  store i128 %add, i128* undef
  ret void
}

The short version is that llc is trying to lower the i128 multiply to a
libcall, which lowers to 4 i32 result regs, but the x86 backend only specifies
2 possible 32-bit reg results (EAX/EDX).  Given that this function doesn't
exist in compiler_rt or libgcc in 32-bit mode, I think that trying to lower to
the libcall is the bug, not the lack of result registers.
Quuxplusone commented 13 years ago
Still fails, updated testcase:

target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
target triple = "i386-apple-darwin10.0.0"

define void @MUL_BIG(i64 %a, i64 %b) nounwind ssp {
entry:
  %conv = zext i64 %a to i128                  ; <i128> [#uses=1]
  %conv2 = zext i64 %b to i128                 ; <i128> [#uses=1]
  %mul = mul i128 %conv, %conv2                   ; <i128> [#uses=1]
  %add = add i128 %mul, 0                         ; <i128> [#uses=1]
  store i128 %add, i128* undef
  ret void
}
Quuxplusone commented 13 years ago

It appears i128 add and several other operators are also broken on x86-32. Until someone volunteers to implement and maintain i128 codegen for 32-bit targets, clang should reject it so that configure scripts don't autodetect it.

Quuxplusone commented 13 years ago

i128 add used to work on x86-32. It is i128 mul that can't be expected to work.

Quuxplusone commented 13 years ago
Hi Duncan,
Can you be a little bit more verbose what you mean with "i128 mul can't be
expected to work"?

Because as a poor user i would go with Dan, either the basic ops can be lowered
(libcall or whatever, fairy dust if it helps), or the compiler should refuse TI-
mode. Some Semi-in-between-state ... is suboptimal. This leads to a lot of
configure testing + ugly ifdefery and explodes the testvector.

Greetings
Jan
Quuxplusone commented 13 years ago
i128 mul cannot be expected to work on x86-32 because there is no library
support
for it (libgcc only supports i64 mul on x86-32).  If library support was added,
or llvm output an appropriate function on the fly, then it would work of course.
Quuxplusone commented 11 years ago
GCC gets this right:
$ gcc -m32 -c -o /dev/null test5.c
test5.c:1:1: error: unable to emulate 'TI'