kernigh updated this revision to Diff 305335. kernigh retitled this revision from "[PowerPC] Fix va_arg in Objective-C on 32-bit ELF targets" to "[PowerPC] Fix va_arg in C++, Objective-C on 32-bit ELF targets". kernigh edited the summary of this revision. kernigh added a comment.
I have updated the diff to use `bool isInt = !Ty->isFloatingType();` and `bool isIndirect = isAggregateTypeForABI(Ty);`. This removes both calls to `Ty->isAggregateType()`. This fixes some C++ types, because aren't aggregates in the C++ language, but do become aggregates in the ABI. The new test ppc32-varargs-method.cpp checks a pointer to a member function, and passes only with both the `isInt` and `isIndirect` changes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D90329/new/ https://reviews.llvm.org/D90329 Files: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGenCXX/ppc32-varargs-method.cpp clang/test/CodeGenObjC/ppc32-varargs-id.m Index: clang/test/CodeGenObjC/ppc32-varargs-id.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/ppc32-varargs-id.m @@ -0,0 +1,33 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -fblocks -emit-llvm -o - %s | FileCheck %s + +#include <stdarg.h> + +id testObject(va_list ap) { + return va_arg(ap, id); +} +// CHECK: @testObject +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to i8** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont + +typedef void (^block)(void); +block testBlock(va_list ap) { + return va_arg(ap, block); +} +// CHECK: @testBlock +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to void ()** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont Index: clang/test/CodeGenCXX/ppc32-varargs-method.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/ppc32-varargs-method.cpp @@ -0,0 +1,20 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -emit-llvm -o - %s | FileCheck %s + +#include <stdarg.h> + +class something; +typedef void (something::*method)(); + +method test(va_list ap) { + return va_arg(ap, method); +} +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to { i32, i32 }** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -4719,13 +4719,12 @@ // }; bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; - bool isInt = - Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType(); + bool isInt = !Ty->isFloatingType(); bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64; // All aggregates are passed indirectly? That doesn't seem consistent // with the argument-lowering code. - bool isIndirect = Ty->isAggregateType(); + bool isIndirect = isAggregateTypeForABI(Ty); CGBuilderTy &Builder = CGF.Builder;
Index: clang/test/CodeGenObjC/ppc32-varargs-id.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/ppc32-varargs-id.m @@ -0,0 +1,33 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -fblocks -emit-llvm -o - %s | FileCheck %s + +#include <stdarg.h> + +id testObject(va_list ap) { + return va_arg(ap, id); +} +// CHECK: @testObject +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to i8** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont + +typedef void (^block)(void); +block testBlock(va_list ap) { + return va_arg(ap, block); +} +// CHECK: @testBlock +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to void ()** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont Index: clang/test/CodeGenCXX/ppc32-varargs-method.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/ppc32-varargs-method.cpp @@ -0,0 +1,20 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -emit-llvm -o - %s | FileCheck %s + +#include <stdarg.h> + +class something; +typedef void (something::*method)(); + +method test(va_list ap) { + return va_arg(ap, method); +} +// CHECK: using_regs: +// CHECK-NEXT: getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %{{[0-9]+}}, i32 0, i32 4 +// CHECK-NEXT: load i8*, i8** %{{[0-9]+}}, align 4 +// CHECK-NEXT: mul i8 %numUsedRegs, 4 +// CHECK-NEXT: getelementptr inbounds i8, i8* %{{[0-9]+}}, i8 %{{[0-9]+}} +// CHECK-NEXT: bitcast i8* %{{[0-9]+}} to { i32, i32 }** +// CHECK-NEXT: add i8 %numUsedRegs, 1 +// CHECK-NEXT: store i8 %{{[0-9]+}}, i8* %gpr, align 4 +// CHECK-NEXT: br label %cont Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -4719,13 +4719,12 @@ // }; bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; - bool isInt = - Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType(); + bool isInt = !Ty->isFloatingType(); bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64; // All aggregates are passed indirectly? That doesn't seem consistent // with the argument-lowering code. - bool isIndirect = Ty->isAggregateType(); + bool isIndirect = isAggregateTypeForABI(Ty); CGBuilderTy &Builder = CGF.Builder;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits