Open Quuxplusone opened 13 years ago
I have to confess I already knew about it. The main reason I never added
support
for this (besides not needing it myself) is I couldn't find a description of the
__float128 type. Is it the standard IEEE quad precision type?
(In reply to comment #1)
> I have to confess I already knew about it. The main reason I never added
> support
> for this (besides not needing it myself) is I couldn't find a description of
> the
> __float128 type. Is it the standard IEEE quad precision type?
As it seems for me - yes. Note that currently LLVM is not pretty good in
supporting fp128 at the codegen level. I believe I had some patches for this
while reviewing systemz backend, but probably I committed them all, I'll check.
On x86 (including x86_64) the compiler quickly barfs on fp128 because its
alignment is not known: nothing is specified in the data layout string...
Attached dl.diff
(1482 bytes, text/plain): data layout patch
This is fixed in the sense that dragonegg now happily outputs IR for the
testcase (see below). However codegen falls over at once:
llvm/include/llvm/Target/TargetLowering.h:171: virtual
llvm::TargetRegisterClass* llvm::TargetLowering::getRegClassFor(llvm::EVT)
const: Assertion `RC && "This value type is not natively supported!"' failed.
Stack dump:
0. Running pass 'X86 DAG->DAG Instruction Selection' on function '@factorial'
Anton, maybe you can comment on this?
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
module asm "\09.ident\09\22GCC: (GNU) 4.5.3 20110304 (prerelease) LLVM:
126934:127093M\22"
@.str = private constant [6 x i8] c"%LLg\0A\00", align 1
define fp128 @factorial(fp128 %X) nounwind readnone {
entry:
%0 = fcmp oeq fp128 %X, 0xL00000000000000000000000000000000
br i1 %0, label %"5", label %"4"
"4": ; preds = %entry
%1 = fadd fp128 %X, 0xL0000000000000000BFFF000000000000
%2 = tail call fp128 @factorial(fp128 %1) nounwind
%3 = fmul fp128 %2, %X
ret fp128 %3
"5": ; preds = %entry
ret fp128 0xL00000000000000003FFF000000000000
}
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
entry:
%0 = getelementptr inbounds i8** %argv, i64 1
%1 = load i8** %0, align 8
%2 = tail call i64 @strtol(i8* noalias nocapture %1, i8** noalias null, i32 10) nounwind
%3 = trunc i64 %2 to i32
%4 = sitofp i32 %3 to fp128
%5 = tail call fp128 @factorial(fp128 %4) nounwind
%6 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), fp128 %5) nounwind
ret i32 undef
}
declare i64 @strtol(i8* noalias, i8** noalias nocapture, i32) nounwind
declare i32 @printf(i8* nocapture, ...) nounwind
We have practically nothing in terms of __float128 support; APFloat works
(AFAIK), but not much else. The following patch is enough to get a little
further, but we then fail in type legalization because we don't know how to
generate fp128 libcalls.
Index: SelectionDAG/TargetLowering.cpp
===================================================================
--- SelectionDAG/TargetLowering.cpp (revision 127954)
+++ SelectionDAG/TargetLowering.cpp (working copy)
@@ -762,6 +762,15 @@
// Decide how to handle f64. If the target does not have native f64 support,
// expand it to i64 and we will be generating soft float library calls.
+ if (!isTypeLegal(MVT::f128)) {
+ NumRegistersForVT[MVT::f128] = NumRegistersForVT[MVT::i128];
+ RegisterTypeForVT[MVT::f128] = RegisterTypeForVT[MVT::i128];
+ TransformToType[MVT::f128] = MVT::i128;
+ ValueTypeActions.setTypeAction(MVT::f128, Expand);
+ }
+
+ // Decide how to handle f64. If the target does not have native f64 support,
+ // expand it to i64 and we will be generating soft float library calls.
if (!isTypeLegal(MVT::f64)) {
NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];
RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64];
_Bug 10980 has been marked as a duplicate of this bug._
dl.diff
(1482 bytes, text/plain)