forked from OSchip/llvm-project
[mips] Promote all integral/enumeration types to the GPR width
Summary: Ensure all integral/enumeration types are appropriately annotated with signext/zeroext. In particular, i32 now has these attributes when using the N32/N64 ABI. This paves the way for accurately representing the way the N32/N64 ABI's promotes integer arguments to i64. Reviewers: atanasyan Reviewed By: atanasyan Subscribers: cfe-commits, theraven Differential Revision: http://reviews.llvm.org/D5961 llvm-svn: 220563
This commit is contained in:
parent
df6d7b1564
commit
5b445b3844
|
@ -5617,7 +5617,8 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
|
|||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
if (Ty->isPromotableIntegerType())
|
||||
// All integral types are promoted to the GPR width.
|
||||
if (Ty->isIntegralOrEnumerationType())
|
||||
return ABIArgInfo::getExtend();
|
||||
|
||||
return ABIArgInfo::getDirect(
|
||||
|
|
|
@ -76,8 +76,8 @@ void test1(void) {
|
|||
// MIPS32: store atomic i32 {{.*}}, i32* @i1 seq_cst
|
||||
// MIPS32: call i64 @__atomic_load_8(i8* bitcast (i64* @ll1 to i8*)
|
||||
// MIPS32: call void @__atomic_store_8(i8* bitcast (i64* @ll1 to i8*), i64
|
||||
// MIPS32: call void @__atomic_load(i32 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
// MIPS32: call void @__atomic_store(i32 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
// MIPS32: call void @__atomic_load(i32 zeroext 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
// MIPS32: call void @__atomic_store(i32 zeroext 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
|
||||
// MIPS64-LABEL: define void @test1
|
||||
// MIPS64: = load atomic i8* @c1 seq_cst
|
||||
|
@ -88,6 +88,6 @@ void test1(void) {
|
|||
// MIPS64: store atomic i32 {{.*}}, i32* @i1 seq_cst
|
||||
// MIPS64: = load atomic i64* @ll1 seq_cst
|
||||
// MIPS64: store atomic i64 {{.*}}, i64* @ll1 seq_cst
|
||||
// MIPS64: call void @__atomic_load(i64 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0)
|
||||
// MIPS64: call void @__atomic_store(i64 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
// MIPS64: call void @__atomic_load(i64 zeroext 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0)
|
||||
// MIPS64: call void @__atomic_store(i64 zeroext 100, i8* getelementptr inbounds ([100 x i8]* @a1, i32 0, i32 0), i8* getelementptr inbounds ([100 x i8]* @a2, i32 0, i32 0)
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
typedef float v4sf __attribute__ ((__vector_size__ (16)));
|
||||
typedef int v4i32 __attribute__ ((__vector_size__ (16)));
|
||||
|
||||
// O32: define void @test_v4sf(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW:#[0-9]+]]
|
||||
// O32: declare i32 @test_v4sf_2(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
|
||||
// N64: define void @test_v4sf(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW:#[0-9]+]]
|
||||
// N64: declare i32 @test_v4sf_2(i64, i64, i32, i64, i64, i64)
|
||||
// O32: define void @test_v4sf(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 signext %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW:#[0-9]+]]
|
||||
// O32: declare i32 @test_v4sf_2(i32, i32, i32, i32, i32 signext, i32, i32, i32, i32, i32)
|
||||
// N64: define void @test_v4sf(i64 %a1.coerce0, i64 %a1.coerce1, i32 signext %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW:#[0-9]+]]
|
||||
// N64: declare i32 @test_v4sf_2(i64, i64, i32 signext, i64, i64, i64)
|
||||
extern test_v4sf_2(v4sf, int, v4sf);
|
||||
void test_v4sf(v4sf a1, int a2, v4sf a3) {
|
||||
test_v4sf_2(a3, a2, a1);
|
||||
}
|
||||
|
||||
// O32: define void @test_v4i32(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW]]
|
||||
// O32: declare i32 @test_v4i32_2(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
|
||||
// N64: define void @test_v4i32(i64 %a1.coerce0, i64 %a1.coerce1, i32 %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW]]
|
||||
// N64: declare i32 @test_v4i32_2(i64, i64, i32, i64, i64, i64)
|
||||
// O32: define void @test_v4i32(i32 %a1.coerce0, i32 %a1.coerce1, i32 %a1.coerce2, i32 %a1.coerce3, i32 signext %a2, i32, i32 %a3.coerce0, i32 %a3.coerce1, i32 %a3.coerce2, i32 %a3.coerce3) [[NUW]]
|
||||
// O32: declare i32 @test_v4i32_2(i32, i32, i32, i32, i32 signext, i32, i32, i32, i32, i32)
|
||||
// N64: define void @test_v4i32(i64 %a1.coerce0, i64 %a1.coerce1, i32 signext %a2, i64, i64 %a3.coerce0, i64 %a3.coerce1) [[NUW]]
|
||||
// N64: declare i32 @test_v4i32_2(i64, i64, i32 signext, i64, i64, i64)
|
||||
extern test_v4i32_2(v4i32, int, v4i32);
|
||||
void test_v4i32(v4i32 a1, int a2, v4i32 a3) {
|
||||
test_v4i32_2(a3, a2, a1);
|
||||
|
|
|
@ -9,9 +9,9 @@ typedef struct {
|
|||
|
||||
// Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries.
|
||||
|
||||
// N64-LABEL: define void @foo1(i32 %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
|
||||
// N64: tail call void @foo2(i32 1, i32 2, i32 %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
|
||||
// N64: declare void @foo2(i32, i32, i32, i64, double, i64, i64, i64, double, i64, i64, i64, i32, i64, double, i64, i64, i64)
|
||||
// N64-LABEL: define void @foo1(i32 signext %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 signext %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
|
||||
// N64: tail call void @foo2(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 signext 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3)
|
||||
// N64: declare void @foo2(i32 signext, i32 signext, i32 signext, i64, double, i64, i64, i64, double, i64, i64, i64, i32 signext, i64, double, i64, i64, i64)
|
||||
|
||||
extern void foo2(int, int, int, S0, S0, int, S0);
|
||||
|
||||
|
@ -21,9 +21,9 @@ void foo1(int a0, S0 a1, S0 a2, int b, S0 a3) {
|
|||
|
||||
// Insert padding before long double argument.
|
||||
//
|
||||
// N64-LABEL: define void @foo3(i32 %a0, i64, fp128 %a1)
|
||||
// N64: tail call void @foo4(i32 1, i32 2, i32 %a0, i64 undef, fp128 %a1)
|
||||
// N64: declare void @foo4(i32, i32, i32, i64, fp128)
|
||||
// N64-LABEL: define void @foo3(i32 signext %a0, i64, fp128 %a1)
|
||||
// N64: tail call void @foo4(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, fp128 %a1)
|
||||
// N64: declare void @foo4(i32 signext, i32 signext, i32 signext, i64, fp128)
|
||||
|
||||
extern void foo4(int, int, int, long double);
|
||||
|
||||
|
@ -34,8 +34,8 @@ void foo3(int a0, long double a1) {
|
|||
// Insert padding after hidden argument.
|
||||
//
|
||||
// N64-LABEL: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0)
|
||||
// N64: call void @foo6(%struct.S0* sret %agg.result, i32 1, i32 2, i64 undef, fp128 %a0)
|
||||
// N64: declare void @foo6(%struct.S0* sret, i32, i32, i64, fp128)
|
||||
// N64: call void @foo6(%struct.S0* sret %agg.result, i32 signext 1, i32 signext 2, i64 undef, fp128 %a0)
|
||||
// N64: declare void @foo6(%struct.S0* sret, i32 signext, i32 signext, i64, fp128)
|
||||
|
||||
extern S0 foo6(int, int, long double);
|
||||
|
||||
|
@ -55,7 +55,7 @@ void foo7(float a0, double a1) {
|
|||
}
|
||||
|
||||
// O32-LABEL: define void @foo9()
|
||||
// O32: declare void @foo10(i32, i32
|
||||
// O32: declare void @foo10(i32 signext, i32
|
||||
|
||||
typedef struct __attribute__((aligned(16))) {
|
||||
int a;
|
||||
|
|
|
@ -10,13 +10,13 @@ long *alloc_long() {
|
|||
return rv;
|
||||
}
|
||||
// O32-LABEL: define i32* @_Z10alloc_longv()
|
||||
// O32: call noalias i8* @_Znwj(i32 4)
|
||||
// O32: call noalias i8* @_Znwj(i32 zeroext 4)
|
||||
|
||||
// N32-LABEL: define i32* @_Z10alloc_longv()
|
||||
// N32: call noalias i8* @_Znwj(i32 4)
|
||||
// N32: call noalias i8* @_Znwj(i32 zeroext 4)
|
||||
|
||||
// N64-LABEL: define i64* @_Z10alloc_longv()
|
||||
// N64: call noalias i8* @_Znwm(i64 8)
|
||||
// N64: call noalias i8* @_Znwm(i64 zeroext 8)
|
||||
|
||||
long *alloc_long_array() {
|
||||
long *rv = new long[2];
|
||||
|
@ -24,13 +24,13 @@ long *alloc_long_array() {
|
|||
}
|
||||
|
||||
// O32-LABEL: define i32* @_Z16alloc_long_arrayv()
|
||||
// O32: call noalias i8* @_Znaj(i32 8)
|
||||
// O32: call noalias i8* @_Znaj(i32 zeroext 8)
|
||||
|
||||
// N32-LABEL: define i32* @_Z16alloc_long_arrayv()
|
||||
// N32: call noalias i8* @_Znaj(i32 8)
|
||||
// N32: call noalias i8* @_Znaj(i32 zeroext 8)
|
||||
|
||||
// N64-LABEL: define i64* @_Z16alloc_long_arrayv()
|
||||
// N64: call noalias i8* @_Znam(i64 16)
|
||||
// N64: call noalias i8* @_Znam(i64 zeroext 16)
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
Loading…
Reference in New Issue