yronglin added a comment.

In D138511#3954143 <https://reviews.llvm.org/D138511#3954143>, @efriedma wrote:

> It looks like AArch64ABIInfo::classifyArgumentType does a slightly more 
> complicated check for "empty"; does that matter here?

Thanks for your comments @efriedma. Good catch!  Current patch has a issue in 
this case(C++ mode):

clang -Xclang -no-opaque-pointers -target aarch64-linux-gnu -emit-llvm -S 
./va_arg.cpp

  typedef __builtin_va_list va_list;
  #define va_start(ap, param) __builtin_va_start(ap, param)
  #define va_end(ap)          __builtin_va_end(ap)
  #define va_arg(ap, type)    __builtin_va_arg(ap, type)
  
  va_list the_list;
  typedef struct {} empty;
  empty empty_record_test(void) {
    return va_arg(the_list, empty);
  }

When use `isEmptyRecord` directly to check empty record, the generated IR is:

  define dso_local void @_Z17empty_record_testv() #0 {
  entry:
    %0 = load i8*, i8** getelementptr inbounds (%"struct.std::__va_list", 
%"struct.std::__va_list"* @the_list, i32 0, i32 0), align 8
    %1 = bitcast i8* %0 to %struct.empty*
    ret void
  }

When use `AArch64ABIInfo::classifyArgumentType(...).isIgnore()` to check empty 
record, the generated IR is:

  define dso_local void @_Z17empty_record_testv() #0 {
  entry:
    %gr_offs = load i32, i32* getelementptr inbounds (%"struct.std::__va_list", 
%"struct.std::__va_list"* @the_list, i32 0, i32 3), align 8
    %0 = icmp sge i32 %gr_offs, 0
    br i1 %0, label %vaarg.on_stack, label %vaarg.maybe_reg
  
  vaarg.maybe_reg:                                  ; preds = %entry
    %new_reg_offs = add i32 %gr_offs, 8
    store i32 %new_reg_offs, i32* getelementptr inbounds 
(%"struct.std::__va_list", %"struct.std::__va_list"* @the_list, i32 0, i32 3), 
align 8
    %inreg = icmp sle i32 %new_reg_offs, 0
    br i1 %inreg, label %vaarg.in_reg, label %vaarg.on_stack
  
  vaarg.in_reg:                                     ; preds = %vaarg.maybe_reg
    %reg_top = load i8*, i8** getelementptr inbounds (%"struct.std::__va_list", 
%"struct.std::__va_list"* @the_list, i32 0, i32 1), align 8
    %1 = getelementptr inbounds i8, i8* %reg_top, i32 %gr_offs
    %2 = bitcast i8* %1 to %struct.empty2*
    br label %vaarg.end
  
  vaarg.on_stack:                                   ; preds = %vaarg.maybe_reg, 
%entry
    %stack = load i8*, i8** getelementptr inbounds (%"struct.std::__va_list", 
%"struct.std::__va_list"* @the_list, i32 0, i32 0), align 8
    %new_stack = getelementptr inbounds i8, i8* %stack, i64 8
    store i8* %new_stack, i8** getelementptr inbounds 
(%"struct.std::__va_list", %"struct.std::__va_list"* @the_list, i32 0, i32 0), 
align 8
    %3 = bitcast i8* %stack to %struct.empty2*
    br label %vaarg.end
  
  vaarg.end:                                        ; preds = %vaarg.on_stack, 
%vaarg.in_reg
    %vaargs.addr = phi %struct.empty2* [ %2, %vaarg.in_reg ], [ %3, 
%vaarg.on_stack ]
    ret void
  }

As far as I know,  according to the comments of the 
`AArch64ABIInfo::classifyArgumentType(...)`, "Empty records are always ignored 
on Darwin, but actually passed in C++ mode elsewhere for GNU compatibility." 
and "GNU C mode. The only argument that gets ignored is an empty one with size 
0.", I think we should ignore arg only if DarwinPCS ABI and empty record in C 
mode. What do you all think about?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138511/new/

https://reviews.llvm.org/D138511

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to