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