[LLVMdev] A question about LegalizeDAG.cpp and VAARG

Richard Pennington rich at pennware.com
Sun Oct 12 06:47:27 PDT 2008


I'm generating code for a target that only supports i32 natively.
My front end is generating VAARG for accessing varargs parameters.

The problem is that I get an assert when I compile this:

#include <stdarg.h>

int main(va_list ap)
{
     typedef double type;
     type tmp;

     tmp = va_arg(ap, type);
}

Bitcode:
; ModuleID = 't0056.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-s0:0:64-f80:32:32"
target triple = "nios2-elf"

define i32 @main(i8*) nounwind {
entry:
         %ap = alloca i8*                ; <i8**> [#uses=2]
         store i8* %0, i8** %ap
         %retval = alloca i32            ; <i32*> [#uses=2]
         store i32 0, i32* %retval
         %tmp = alloca double            ; <double*> [#uses=1]
         %1 = va_arg i8** %ap, double            ; <double> [#uses=1]
         store double %1, double* %tmp
         br label %return

return:         ; preds = %entry
         %2 = load i32* %retval          ; <i32> [#uses=1]
         ret i32 %2
}

If I make "type" long long, it works OK.

I tracked the problem down to this:
In the beginning of SelectionDAGLegalize::ExpandOp there is a call to
getTypeToTransformTo to get the type of the expanded parts.
In the case of i64, it returns i32 (as expected).
In the case of f64, it returns i64. The i64 causes the assert later in 
LegalizeOP(Hi).

Looking at getTypeToTransformTo it seems that it is doing what it is
supposed to do, at least according to the comments.

My question is this: What is the correct way to fix this? I can call
getTypeToTransformTo twice and get the correct result, but that seems
wrong.
Should the Hi and Lo values generated in VAARG should be expanded? If
so, how?

-Rich



More information about the llvm-dev mailing list