[llvm-dev] varargs, the x86, and clang

Eric Christopher via llvm-dev llvm-dev at lists.llvm.org
Tue Sep 29 07:41:20 PDT 2015


On Mon, Sep 28, 2015, 4:07 PM Preston Briggs via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> When I use clang on an x86-64 to spit out the LLVM, like this
>
> clang -O -S -emit-llvm varargstest.c
>
>
> where varargstest.c looks like this
>
> int add_em_up(int count, ...) {
>   va_list ap;
>   int i, sum;
>   va_start(ap, count);
>   sum = 0;
>   for (i = 0; i < count; i++)
>     sum += va_arg(ap, int);
>   va_end(ap);
>   return sum;
> }
>
>
> I see LLVM that looks like it's been customized for the x86-64,
> versus the varargs stuff I was led to expect from the LLVM IR
> documentation.
>
> define i32 @add_em_up(i32 %count, ...) #0 {
> entry:
>   %ap = alloca [1 x %struct.__va_list_tag], align 16
>   %arraydecay1 = bitcast [1 x %struct.__va_list_tag]* %ap to i8*
>   call void @llvm.va_start(i8* %arraydecay1)
>   %cmp7 = icmp sgt i32 %count, 0
>   br i1 %cmp7, label %for.body.lr.ph, label %for.end
>
> for.body.lr.ph:                                   ; preds = %entry
>   %gp_offset_p = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap,
> i64 0, i64 0, i32 0
>   %0 = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i64 0, i64
> 0, i32 3
>   %overflow_arg_area_p = getelementptr inbounds [1 x
> %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 2
>   %gp_offset.pre = load i32* %gp_offset_p, align 16
>   br label %for.body
>
> for.body:                                         ; preds = %vaarg.end, %
> for.body.lr.ph
>   %gp_offset = phi i32 [ %gp_offset.pre, %for.body.lr.ph ], [
> %gp_offset10, %vaarg.end ]
>   %sum.09 = phi i32 [ 0, %for.body.lr.ph ], [ %add, %vaarg.end ]
>   %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %vaarg.end ]
>   %fits_in_gp = icmp ult i32 %gp_offset, 41
>   br i1 %fits_in_gp, label %vaarg.in_reg, label %vaarg.in_mem
>
> vaarg.in_reg:                                     ; preds = %for.body
>   %reg_save_area = load i8** %0, align 16
>   %1 = sext i32 %gp_offset to i64
>   %2 = getelementptr i8* %reg_save_area, i64 %1
>   %3 = add i32 %gp_offset, 8
>   store i32 %3, i32* %gp_offset_p, align 16
>   br label %vaarg.end
>
> vaarg.in_mem:                                     ; preds = %for.body
>   %overflow_arg_area = load i8** %overflow_arg_area_p, align 8
>   %overflow_arg_area.next = getelementptr i8* %overflow_arg_area, i64 8
>   store i8* %overflow_arg_area.next, i8** %overflow_arg_area_p, align 8
>   br label %vaarg.end
>
> vaarg.end:                                        ; preds = %vaarg.in_mem,
> %vaarg.in_reg
>   %gp_offset10 = phi i32 [ %3, %vaarg.in_reg ], [ %gp_offset,
> %vaarg.in_mem ]
>   %vaarg.addr.in = phi i8* [ %2, %vaarg.in_reg ], [ %overflow_arg_area,
> %vaarg.in_mem ]
>   %vaarg.addr = bitcast i8* %vaarg.addr.in to i32*
>   %4 = load i32* %vaarg.addr, align 4
>   %add = add nsw i32 %4, %sum.09
>   %inc = add nsw i32 %i.08, 1
>   %exitcond = icmp eq i32 %inc, %count
>   br i1 %exitcond, label %for.end, label %for.body
>
> for.end:                                          ; preds = %vaarg.end,
> %entry
>   %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %vaarg.end ]
>   call void @llvm.va_end(i8* %arraydecay1)
>   ret i32 %sum.0.lcssa
> }
>
>
> Notice at the bottom of the block labeled "for.body" that there's a test
> that determines
> whether to look for an argument on the stack or in a register. I see
> something similar w/ or w/o the -O flag.
>
> This isn't what I was led to expect by the LLVM IR documentation.
> Is there a way to avoid this "premature" optimization?
> I tried things like -arch mips and -march=mips but get complaints
> about unrecognized flags (-arch) or unknown target architecture CPU 'mips'.
> Why's that? The man page suggests both should work.
>

-arch really only works for Darwin. -March works in a way that you aren't
thinking about, basically clang is a cross compiler by default, but you do
need to specify a triple on the command line using -target.

-eric


> Thanks,
> Preston
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150929/cbffe04e/attachment.html>


More information about the llvm-dev mailing list