clang: Use ptrmask for pointer alignment
Avoid using ptrtoint/inttoptr.
This commit is contained in:
parent
245f26a430
commit
8e009348e8
@ -295,17 +295,13 @@ LLVM_DUMP_METHOD void ABIArgInfo::dump() const {
|
||||
static llvm::Value *emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
|
||||
llvm::Value *Ptr,
|
||||
CharUnits Align) {
|
||||
llvm::Value *PtrAsInt = Ptr;
|
||||
// OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
|
||||
PtrAsInt = CGF.Builder.CreatePtrToInt(PtrAsInt, CGF.IntPtrTy);
|
||||
PtrAsInt = CGF.Builder.CreateAdd(PtrAsInt,
|
||||
llvm::ConstantInt::get(CGF.IntPtrTy, Align.getQuantity() - 1));
|
||||
PtrAsInt = CGF.Builder.CreateAnd(PtrAsInt,
|
||||
llvm::ConstantInt::get(CGF.IntPtrTy, -Align.getQuantity()));
|
||||
PtrAsInt = CGF.Builder.CreateIntToPtr(PtrAsInt,
|
||||
Ptr->getType(),
|
||||
Ptr->getName() + ".aligned");
|
||||
return PtrAsInt;
|
||||
llvm::Value *RoundUp = CGF.Builder.CreateConstInBoundsGEP1_32(
|
||||
CGF.Builder.getInt8Ty(), Ptr, Align.getQuantity() - 1);
|
||||
return CGF.Builder.CreateIntrinsic(
|
||||
llvm::Intrinsic::ptrmask, {CGF.AllocaInt8PtrTy, CGF.IntPtrTy},
|
||||
{RoundUp, llvm::ConstantInt::get(CGF.IntPtrTy, -Align.getQuantity())},
|
||||
nullptr, Ptr->getName() + ".aligned");
|
||||
}
|
||||
|
||||
/// Emit va_arg for a platform using the common void* representation,
|
||||
|
||||
@ -21,26 +21,22 @@ vector double vector_varargs(int count, ...) {
|
||||
|
||||
// AIX32: for.body:
|
||||
// AIX32-NEXT: %argp.cur = load ptr, ptr %arg_list, align 4
|
||||
// AIX32-NEXT: %2 = ptrtoint ptr %argp.cur to i32
|
||||
// AIX32-NEXT: %3 = add i32 %2, 15
|
||||
// AIX32-NEXT: %4 = and i32 %3, -16
|
||||
// AIX32-NEXT: %argp.cur.aligned = inttoptr i32 %4 to ptr
|
||||
// AIX32-NEXT: %2 = getelementptr inbounds i8, ptr %argp.cur, i32 15
|
||||
// AIX32-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i32(ptr %2, i32 -16)
|
||||
// AIX32-NEXT: %argp.next = getelementptr inbounds i8, ptr %argp.cur.aligned, i32 16
|
||||
// AIX32-NEXT: store ptr %argp.next, ptr %arg_list, align 4
|
||||
// AIX32-NEXT: %5 = load <2 x double>, ptr %argp.cur.aligned, align 16
|
||||
// AIX32-NEXT: store <2 x double> %5, ptr %ret, align 16
|
||||
// AIX32-NEXT: %3 = load <2 x double>, ptr %argp.cur.aligned, align 16
|
||||
// AIX32-NEXT: store <2 x double> %3, ptr %ret, align 16
|
||||
// AIX32-NEXT: br label %for.inc
|
||||
|
||||
// AIX64: for.body:
|
||||
// AIX64-NEXT: %argp.cur = load ptr, ptr %arg_list, align 8
|
||||
// AIX64-NEXT: %2 = ptrtoint ptr %argp.cur to i64
|
||||
// AIX64-NEXT: %3 = add i64 %2, 15
|
||||
// AIX64-NEXT: %4 = and i64 %3, -16
|
||||
// AIX64-NEXT: %argp.cur.aligned = inttoptr i64 %4 to ptr
|
||||
// AIX64-NEXT: %2 = getelementptr inbounds i8, ptr %argp.cur, i32 15
|
||||
// AIX64-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i64(ptr %2, i64 -16)
|
||||
// AIX64-NEXT: %argp.next = getelementptr inbounds i8, ptr %argp.cur.aligned, i64 16
|
||||
// AIX64-NEXT: store ptr %argp.next, ptr %arg_list, align 8
|
||||
// AIX64-NEXT: %5 = load <2 x double>, ptr %argp.cur.aligned, align 16
|
||||
// AIX64-NEXT: store <2 x double> %5, ptr %ret, align 16
|
||||
// AIX64-NEXT: %3 = load <2 x double>, ptr %argp.cur.aligned, align 16
|
||||
// AIX64-NEXT: store <2 x double> %3, ptr %ret, align 16
|
||||
// AIX64-NEXT: br label %for.inc
|
||||
|
||||
|
||||
|
||||
@ -37,10 +37,8 @@ void testva (int n, ...)
|
||||
// CHECK-PPC-NEXT: store i8 8, ptr [[GPRPTR]], align 4
|
||||
// CHECK-PPC-NEXT: [[OVERFLOW_AREA_P:%[0-9]+]] = getelementptr inbounds %struct.__va_list_tag, ptr [[ARRAYDECAY]], i32 0, i32 3
|
||||
// CHECK-PPC-NEXT: [[OVERFLOW_AREA:%.+]] = load ptr, ptr [[OVERFLOW_AREA_P]], align 4
|
||||
// CHECK-PPC-NEXT: %{{[0-9]+}} = ptrtoint ptr %argp.cur to i32
|
||||
// CHECK-PPC-NEXT: %{{[0-9]+}} = add i32 %{{[0-9]+}}, 7
|
||||
// CHECK-PPC-NEXT: %{{[0-9]+}} = and i32 %{{[0-9]+}}, -8
|
||||
// CHECK-PPC-NEXT: %argp.cur.aligned = inttoptr i32 %{{[0-9]+}} to ptr
|
||||
// CHECK-PPC-NEXT: [[GEP_ALIGN:%[0-9]+]] = getelementptr inbounds i8, ptr %argp.cur, i32 7
|
||||
// CHECK-PPC-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i32(ptr [[GEP_ALIGN]], i32 -8)
|
||||
// CHECK-PPC-NEXT: [[NEW_OVERFLOW_AREA:%[0-9]+]] = getelementptr inbounds i8, ptr %argp.cur.aligned, i32 4
|
||||
// CHECK-PPC-NEXT: store ptr [[NEW_OVERFLOW_AREA:%[0-9]+]], ptr [[OVERFLOW_AREA_P]], align 4
|
||||
// CHECK-PPC-NEXT: br label %[[CONT]]
|
||||
@ -51,7 +49,7 @@ void testva (int n, ...)
|
||||
// CHECK-PPC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 %t, ptr align 8 [[AGGR]], i32 16, i1 false)
|
||||
|
||||
int v = va_arg (ap, int);
|
||||
|
||||
|
||||
// CHECK: getelementptr inbounds i8, ptr %{{[a-z.0-9]*}}, i64 4
|
||||
// CHECK-PPC: [[ARRAYDECAY:%[a-z0-9]+]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr %ap, i32 0, i32 0
|
||||
// CHECK-PPC-NEXT: [[GPRPTR:%.+]] = getelementptr inbounds %struct.__va_list_tag, ptr [[ARRAYDECAY]], i32 0, i32 0
|
||||
|
||||
@ -77,10 +77,8 @@ struct test1 test1va (int x, ...)
|
||||
|
||||
// CHECK: define{{.*}} void @test2va(ptr noalias sret(%struct.test2) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...)
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK: %[[TMP0:[^ ]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
|
||||
// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to ptr
|
||||
// CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 16
|
||||
// CHECK: store ptr %[[NEXT]], ptr %ap
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[AGG_RESULT]], ptr align 16 %[[ALIGN]], i64 16, i1 false)
|
||||
@ -96,10 +94,8 @@ struct test2 test2va (int x, ...)
|
||||
|
||||
// CHECK: define{{.*}} void @test3va(ptr noalias sret(%struct.test3) align 32 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...)
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK: %[[TMP0:[^ ]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
|
||||
// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to ptr
|
||||
// CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 32
|
||||
// CHECK: store ptr %[[NEXT]], ptr %ap
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 32 %[[AGG_RESULT]], ptr align 16 %[[ALIGN]], i64 32, i1 false)
|
||||
@ -178,10 +174,8 @@ struct test_longdouble testva_longdouble (int x, ...)
|
||||
|
||||
// CHECK: define{{.*}} void @testva_vector(ptr noalias sret(%struct.test_vector) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...)
|
||||
// CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap
|
||||
// CHECK: %[[TMP0:[^ ]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
|
||||
// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to ptr
|
||||
// CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 16
|
||||
// CHECK: store ptr %[[NEXT]], ptr %ap
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[AGG_RESULT]], ptr align 16 %[[ALIGN]], i64 16, i1 false)
|
||||
|
||||
@ -33,10 +33,8 @@ void foo_ls(ldbl128_s);
|
||||
// OMP-HOST-LABEL: define{{.*}} void @omp(
|
||||
// OMP-HOST: call void @llvm.va_start(ptr %[[AP:[0-9a-zA-Z_.]+]])
|
||||
// OMP-HOST: %[[CUR:[0-9a-zA-Z_.]+]] = load ptr, ptr %[[AP]], align 8
|
||||
// OMP-HOST: %[[V0:[0-9a-zA-Z_.]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// OMP-HOST: %[[V1:[0-9a-zA-Z_.]+]] = add i64 %[[V0]], 15
|
||||
// OMP-HOST: %[[V2:[0-9a-zA-Z_.]+]] = and i64 %[[V1]], -16
|
||||
// OMP-HOST: %[[ALIGN:[0-9a-zA-Z_.]+]] = inttoptr i64 %[[V2]] to ptr
|
||||
// OMP-HOST: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// OMP-HOST: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// OMP-HOST: %[[V4:[0-9a-zA-Z_.]+]] = load fp128, ptr %[[ALIGN]], align 16
|
||||
// OMP-HOST: call void @foo_ld(fp128 noundef %[[V4]])
|
||||
void omp(int n, ...) {
|
||||
@ -53,10 +51,8 @@ void omp(int n, ...) {
|
||||
// IEEE-LABEL: define{{.*}} void @f128
|
||||
// IEEE: call void @llvm.va_start(ptr %[[AP:[0-9a-zA-Z_.]+]])
|
||||
// IEEE: %[[CUR:[0-9a-zA-Z_.]+]] = load ptr, ptr %[[AP]]
|
||||
// IEEE: %[[V0:[0-9a-zA-Z_.]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// IEEE: %[[V1:[0-9a-zA-Z_.]+]] = add i64 %[[V0]], 15
|
||||
// IEEE: %[[V2:[0-9a-zA-Z_.]+]] = and i64 %[[V1]], -16
|
||||
// IEEE: %[[ALIGN:[0-9a-zA-Z_.]+]] = inttoptr i64 %[[V2]] to ptr
|
||||
// IEEE: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// IEEE: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// IEEE: %[[V4:[0-9a-zA-Z_.]+]] = load fp128, ptr %[[ALIGN]], align 16
|
||||
// IEEE: call void @foo_fq(fp128 noundef %[[V4]])
|
||||
// IEEE: call void @llvm.va_end(ptr %[[AP]])
|
||||
@ -70,10 +66,8 @@ void f128(int n, ...) {
|
||||
// IEEE-LABEL: define{{.*}} void @long_double
|
||||
// IEEE: call void @llvm.va_start(ptr %[[AP:[0-9a-zA-Z_.]+]])
|
||||
// IEEE: %[[CUR:[0-9a-zA-Z_.]+]] = load ptr, ptr %[[AP]]
|
||||
// IEEE: %[[V0:[0-9a-zA-Z_.]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// IEEE: %[[V1:[0-9a-zA-Z_.]+]] = add i64 %[[V0]], 15
|
||||
// IEEE: %[[V2:[0-9a-zA-Z_.]+]] = and i64 %[[V1]], -16
|
||||
// IEEE: %[[ALIGN:[0-9a-zA-Z_.]+]] = inttoptr i64 %[[V2]] to ptr
|
||||
// IEEE: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// IEEE: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// IEEE: %[[V4:[0-9a-zA-Z_.]+]] = load fp128, ptr %[[ALIGN]], align 16
|
||||
// IEEE: call void @foo_ld(fp128 noundef %[[V4]])
|
||||
// IEEE: call void @llvm.va_end(ptr %[[AP]])
|
||||
@ -94,10 +88,8 @@ void long_double(int n, ...) {
|
||||
// IEEE-LABEL: define{{.*}} void @long_double_struct
|
||||
// IEEE: call void @llvm.va_start(ptr %[[AP:[0-9a-zA-Z_.]+]])
|
||||
// IEEE: %[[CUR:[0-9a-zA-Z_.]+]] = load ptr, ptr %[[AP]]
|
||||
// IEEE: %[[P0:[0-9a-zA-Z_.]+]] = ptrtoint ptr %[[CUR]] to i64
|
||||
// IEEE: %[[P1:[0-9a-zA-Z_.]+]] = add i64 %[[P0]], 15
|
||||
// IEEE: %[[P2:[0-9a-zA-Z_.]+]] = and i64 %[[P1]], -16
|
||||
// IEEE: %[[ALIGN:[0-9a-zA-Z_.]+]] = inttoptr i64 %[[P2]] to ptr
|
||||
// IEEE: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15
|
||||
// IEEE: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16)
|
||||
// IEEE: %[[V0:[0-9a-zA-Z_.]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 16
|
||||
// IEEE: store ptr %[[V0]], ptr %[[AP]], align 8
|
||||
// IEEE: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[TMP:[0-9a-zA-Z_.]+]], ptr align 16 %[[ALIGN]], i64 16, i1 false)
|
||||
|
||||
@ -111,17 +111,15 @@ int f_va_1(char *fmt, ...) {
|
||||
// CHECK-NEXT: store ptr [[FMT]], ptr [[FMT_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARGP_CUR]] to i32
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 7
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -8
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = inttoptr i32 [[TMP2]] to ptr
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8)
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP3]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP1]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load double, ptr [[V]], align 8
|
||||
// CHECK-NEXT: ret double [[TMP4]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load double, ptr [[V]], align 8
|
||||
// CHECK-NEXT: ret double [[TMP2]]
|
||||
//
|
||||
double f_va_2(char *fmt, ...) {
|
||||
__builtin_va_list va;
|
||||
@ -146,32 +144,28 @@ double f_va_2(char *fmt, ...) {
|
||||
// CHECK-NEXT: store ptr [[FMT]], ptr [[FMT_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARGP_CUR]] to i32
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 7
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -8
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = inttoptr i32 [[TMP2]] to ptr
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8)
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP3]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP1]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i32 4
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARGP_CUR1]], align 4
|
||||
// CHECK-NEXT: store i32 [[TMP4]], ptr [[W]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARGP_CUR1]], align 4
|
||||
// CHECK-NEXT: store i32 [[TMP2]], ptr [[W]], align 4
|
||||
// CHECK-NEXT: [[ARGP_CUR3:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[ARGP_CUR3]] to i32
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], 7
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], -8
|
||||
// CHECK-NEXT: [[ARGP_CUR3_ALIGNED:%.*]] = inttoptr i32 [[TMP7]] to ptr
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3]], i32 7
|
||||
// CHECK-NEXT: [[ARGP_CUR3_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP3]], i32 -8)
|
||||
// CHECK-NEXT: [[ARGP_NEXT4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3_ALIGNED]], i32 8
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT4]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = load double, ptr [[ARGP_CUR3_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP8]], ptr [[X]], align 8
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load double, ptr [[ARGP_CUR3_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store double [[TMP4]], ptr [[X]], align 8
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = load double, ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[TMP10:%.*]] = load double, ptr [[X]], align 8
|
||||
// CHECK-NEXT: [[ADD:%.*]] = fadd double [[TMP9]], [[TMP10]]
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = load double, ptr [[X]], align 8
|
||||
// CHECK-NEXT: [[ADD:%.*]] = fadd double [[TMP5]], [[TMP6]]
|
||||
// CHECK-NEXT: ret double [[ADD]]
|
||||
//
|
||||
double f_va_3(char *fmt, ...) {
|
||||
|
||||
@ -166,17 +166,15 @@ int f_va_1(char *fmt, ...) {
|
||||
// CHECK-NEXT: store ptr [[FMT]], ptr [[FMT_ADDR]], align 8
|
||||
// CHECK-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARGP_CUR]] to i64
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 15
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], -16
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = inttoptr i64 [[TMP2]] to ptr
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 15
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[TMP0]], i64 -16)
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i64 16
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load fp128, ptr [[ARGP_CUR_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP3]], ptr [[V]], align 16
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load fp128, ptr [[ARGP_CUR_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP1]], ptr [[V]], align 16
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load fp128, ptr [[V]], align 16
|
||||
// CHECK-NEXT: ret fp128 [[TMP4]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr [[V]], align 16
|
||||
// CHECK-NEXT: ret fp128 [[TMP2]]
|
||||
//
|
||||
long double f_va_2(char *fmt, ...) {
|
||||
__builtin_va_list va;
|
||||
@ -201,32 +199,28 @@ long double f_va_2(char *fmt, ...) {
|
||||
// CHECK-NEXT: store ptr [[FMT]], ptr [[FMT_ADDR]], align 8
|
||||
// CHECK-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARGP_CUR]] to i64
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 15
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], -16
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = inttoptr i64 [[TMP2]] to ptr
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 15
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[TMP0]], i64 -16)
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i64 16
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load fp128, ptr [[ARGP_CUR_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP3]], ptr [[V]], align 16
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load fp128, ptr [[ARGP_CUR_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP1]], ptr [[V]], align 16
|
||||
// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i64 8
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARGP_CUR1]], align 8
|
||||
// CHECK-NEXT: store i32 [[TMP4]], ptr [[W]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARGP_CUR1]], align 8
|
||||
// CHECK-NEXT: store i32 [[TMP2]], ptr [[W]], align 4
|
||||
// CHECK-NEXT: [[ARGP_CUR3:%.*]] = load ptr, ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[ARGP_CUR3]] to i64
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], 15
|
||||
// CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], -16
|
||||
// CHECK-NEXT: [[ARGP_CUR3_ALIGNED:%.*]] = inttoptr i64 [[TMP7]] to ptr
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3]], i32 15
|
||||
// CHECK-NEXT: [[ARGP_CUR3_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[TMP3]], i64 -16)
|
||||
// CHECK-NEXT: [[ARGP_NEXT4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3_ALIGNED]], i64 16
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT4]], ptr [[VA]], align 8
|
||||
// CHECK-NEXT: [[TMP8:%.*]] = load fp128, ptr [[ARGP_CUR3_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP8]], ptr [[X]], align 16
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load fp128, ptr [[ARGP_CUR3_ALIGNED]], align 16
|
||||
// CHECK-NEXT: store fp128 [[TMP4]], ptr [[X]], align 16
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP9:%.*]] = load fp128, ptr [[V]], align 16
|
||||
// CHECK-NEXT: [[TMP10:%.*]] = load fp128, ptr [[X]], align 16
|
||||
// CHECK-NEXT: [[ADD:%.*]] = fadd fp128 [[TMP9]], [[TMP10]]
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = load fp128, ptr [[V]], align 16
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = load fp128, ptr [[X]], align 16
|
||||
// CHECK-NEXT: [[ADD:%.*]] = fadd fp128 [[TMP5]], [[TMP6]]
|
||||
// CHECK-NEXT: ret fp128 [[ADD]]
|
||||
//
|
||||
long double f_va_3(char *fmt, ...) {
|
||||
|
||||
@ -14,11 +14,11 @@
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARGP_CUR]], align 4
|
||||
// CHECK-NEXT: store i32 [[TMP1]], ptr [[V]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARGP_CUR]], align 4
|
||||
// CHECK-NEXT: store i32 [[TMP0]], ptr [[V]], align 4
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[V]], align 4
|
||||
// CHECK-NEXT: ret i32 [[TMP2]]
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[V]], align 4
|
||||
// CHECK-NEXT: ret i32 [[TMP1]]
|
||||
//
|
||||
int test_i32(char *fmt, ...) {
|
||||
va_list va;
|
||||
@ -40,17 +40,15 @@ int test_i32(char *fmt, ...) {
|
||||
// CHECK-NEXT: store ptr [[FMT]], ptr [[FMT_ADDR]], align 4
|
||||
// CHECK-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARGP_CUR]] to i32
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 7
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -8
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = inttoptr i32 [[TMP2]] to ptr
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7
|
||||
// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8)
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store i64 [[TMP4]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARGP_CUR_ALIGNED]], align 8
|
||||
// CHECK-NEXT: store i64 [[TMP1]], ptr [[V]], align 8
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = load i64, ptr [[V]], align 8
|
||||
// CHECK-NEXT: ret i64 [[TMP5]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[V]], align 8
|
||||
// CHECK-NEXT: ret i64 [[TMP2]]
|
||||
//
|
||||
long long test_i64(char *fmt, ...) {
|
||||
va_list va;
|
||||
@ -79,8 +77,8 @@ struct S {
|
||||
// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 [[TMP1]], i32 12, i1 false)
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 [[TMP0]], i32 12, i1 false)
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
@ -109,11 +107,11 @@ struct Z {};
|
||||
// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 0
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[U]], ptr align 4 [[ARGP_CUR]], i32 0, i1 false)
|
||||
// CHECK-NEXT: [[ARGP_CUR2:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[ARGP_NEXT3:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR2]], i32 4
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT3]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARGP_CUR2]], align 4
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 [[TMP4]], i32 12, i1 false)
|
||||
// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i32 4
|
||||
// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[VA]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGP_CUR1]], align 4
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT]], ptr align 4 [[TMP0]], i32 12, i1 false)
|
||||
// CHECK-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
|
||||
@ -304,9 +304,8 @@ struct s62 { T62 x; int y; } __attribute((packed, aligned(8)));
|
||||
void f62(int x, struct s62 y) {}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} i32 @f63
|
||||
// CHECK: ptrtoint
|
||||
// CHECK: and {{.*}}, -16
|
||||
// CHECK: inttoptr
|
||||
// CHECK: getelementptr inbounds i8, ptr {{.*}}, i32 15
|
||||
// CHECK: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -16)
|
||||
typedef int T63 __attribute((vector_size(16)));
|
||||
struct s63 { T63 x; int y; };
|
||||
int f63(int i, ...) {
|
||||
@ -326,9 +325,8 @@ struct s65 { signed char a[0]; float b; };
|
||||
struct s65 f65(void) { return (struct s65){{},2}; }
|
||||
|
||||
// CHECK-LABEL: define{{.*}} <2 x i64> @f66
|
||||
// CHECK: ptrtoint
|
||||
// CHECK: and {{.*}}, -16
|
||||
// CHECK: inttoptr
|
||||
// CHECK: getelementptr inbounds i8, ptr {{.*}}, i32 15
|
||||
// CHECK: call ptr @llvm.ptrmask.p0.i32(ptr {{.*}}, i32 -16)
|
||||
typedef int T66 __attribute((vector_size(16)));
|
||||
T66 f66(int i, ...) {
|
||||
__builtin_va_list ap;
|
||||
|
||||
@ -335,10 +335,8 @@ void func43(SA s) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} i32 @f44
|
||||
// CHECK: ptrtoint
|
||||
// CHECK-NEXT: add i64 %{{[0-9]+}}, 31
|
||||
// CHECK-NEXT: and i64 %{{[0-9]+}}, -32
|
||||
// CHECK-NEXT: inttoptr
|
||||
// CHECK: getelementptr inbounds i8, ptr %{{.+}}, i32 31
|
||||
// CHECK-NEXT: call ptr @llvm.ptrmask.p0.i64(ptr %{{[0-9]+}}, i64 -32)
|
||||
typedef int T44 __attribute((vector_size(32)));
|
||||
struct s44 { T44 x; int y; };
|
||||
int f44(int i, ...) {
|
||||
|
||||
@ -16,8 +16,7 @@ typedef __attribute__(( ext_vector_type(5) )) short __short5;
|
||||
double varargs_vec_2i(int fixed, ...) {
|
||||
// CHECK: varargs_vec_2i
|
||||
// CHECK: [[VAR:%.*]] = alloca <2 x i32>, align 8
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
// CHECK: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 8
|
||||
// CHECK: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
|
||||
@ -29,8 +28,7 @@ double varargs_vec_2i(int fixed, ...) {
|
||||
// APCS-GNU: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
|
||||
// ANDROID: varargs_vec_2i
|
||||
// ANDROID: [[VAR:%.*]] = alloca <2 x i32>, align 8
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
// ANDROID: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 8
|
||||
// ANDROID: store <2 x i32> [[VEC]], ptr [[VAR]], align 8
|
||||
@ -85,8 +83,7 @@ double test_3c(__char3 *in) {
|
||||
double varargs_vec_5c(int fixed, ...) {
|
||||
// CHECK: varargs_vec_5c
|
||||
// CHECK: [[VAR:%.*]] = alloca <5 x i8>, align 8
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
// CHECK: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 8
|
||||
// CHECK: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
|
||||
@ -98,8 +95,7 @@ double varargs_vec_5c(int fixed, ...) {
|
||||
// APCS-GNU: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
|
||||
// ANDROID: varargs_vec_5c
|
||||
// ANDROID: [[VAR:%.*]] = alloca <5 x i8>, align 8
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
// ANDROID: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 8
|
||||
// ANDROID: store <5 x i8> [[VEC]], ptr [[VAR]], align 8
|
||||
@ -125,8 +121,7 @@ double test_5c(__char5 *in) {
|
||||
double varargs_vec_9c(int fixed, ...) {
|
||||
// CHECK: varargs_vec_9c
|
||||
// CHECK: [[VAR:%.*]] = alloca <9 x i8>, align 16
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
// CHECK: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8
|
||||
// CHECK: store <9 x i8> [[T0]], ptr [[VAR]], align 16
|
||||
@ -138,8 +133,7 @@ double varargs_vec_9c(int fixed, ...) {
|
||||
// APCS-GNU: store <9 x i8> [[VEC]], ptr [[VAR]], align 16
|
||||
// ANDROID: varargs_vec_9c
|
||||
// ANDROID: [[VAR:%.*]] = alloca <9 x i8>, align 16
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
// ANDROID: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8
|
||||
// ANDROID: store <9 x i8> [[T0]], ptr [[VAR]], align 16
|
||||
@ -194,8 +188,7 @@ double test_19c(__char19 *in) {
|
||||
double varargs_vec_3s(int fixed, ...) {
|
||||
// CHECK: varargs_vec_3s
|
||||
// CHECK: alloca <3 x i16>, align 8
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
// APCS-GNU: varargs_vec_3s
|
||||
// APCS-GNU: [[VAR:%.*]] = alloca <3 x i16>, align 8
|
||||
@ -204,8 +197,7 @@ double varargs_vec_3s(int fixed, ...) {
|
||||
// APCS-GNU: [[VEC:%.*]] = load <3 x i16>, ptr [[AP]], align 4
|
||||
// ANDROID: varargs_vec_3s
|
||||
// ANDROID: alloca <3 x i16>, align 8
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8
|
||||
va_list ap;
|
||||
double sum = fixed;
|
||||
@ -229,8 +221,7 @@ double test_3s(__short3 *in) {
|
||||
double varargs_vec_5s(int fixed, ...) {
|
||||
// CHECK: varargs_vec_5s
|
||||
// CHECK: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
// CHECK: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8
|
||||
// CHECK: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16
|
||||
@ -241,8 +232,7 @@ double varargs_vec_5s(int fixed, ...) {
|
||||
// APCS-GNU: [[VEC:%.*]] = load <5 x i16>, ptr [[AP]], align 4
|
||||
// ANDROID: varargs_vec_5s
|
||||
// ANDROID: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
// ANDROID: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8
|
||||
// ANDROID: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16
|
||||
@ -274,16 +264,14 @@ typedef struct
|
||||
|
||||
double varargs_struct(int fixed, ...) {
|
||||
// CHECK: varargs_struct
|
||||
// CHECK: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
// APCS-GNU: varargs_struct
|
||||
// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca %struct.StructWithVec
|
||||
// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i32 16
|
||||
// APCS-GNU: call void @llvm.memcpy
|
||||
// ANDROID: varargs_struct
|
||||
// ANDROID: [[ALIGN:%.*]] = and i32 {{%.*}}, -8
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = inttoptr i32 [[ALIGN]] to ptr
|
||||
// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)
|
||||
// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16
|
||||
va_list ap;
|
||||
double sum = fixed;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// REQUIRES: arm-registered-target
|
||||
// RUN: %clang_cc1 -triple arm -target-abi aapcs %s -emit-llvm -o - | FileCheck -check-prefix=AAPCS %s
|
||||
// RUN: %clang_cc1 -triple arm -target-abi apcs-gnu %s -emit-llvm -o - | FileCheck -check-prefix=APCS-GNU %s
|
||||
/*
|
||||
/*
|
||||
* Check that va_arg accesses stack according to ABI alignment
|
||||
* long long and double require 8-byte alignment under AAPCS
|
||||
* however, they only require 4-byte alignment under APCS
|
||||
@ -11,10 +11,11 @@ long long t1(int i, ...) {
|
||||
// APCS-GNU: t1
|
||||
__builtin_va_list ap;
|
||||
__builtin_va_start(ap, i);
|
||||
// AAPCS: add i32 %{{.*}} 7
|
||||
// AAPCS: and i32 %{{.*}} -8
|
||||
// APCS-GNU-NOT: add i32 %{{.*}} 7
|
||||
// APCS-GNU-NOT: and i32 %{{.*}} -8
|
||||
// AAPCS: [[ADD:%.*]] = getelementptr inbounds i8, ptr %argp.cur, i32 7
|
||||
// AAPCS = call ptr @llvm.ptrmask.p0.i32(ptr [[ADD]], i32 -8)
|
||||
|
||||
// APCS-GNU-NOT: getelementptr {{.*}}, i32 7
|
||||
// APCS-GNU-NOT: llvm.ptrmask.p0
|
||||
long long ll = __builtin_va_arg(ap, long long);
|
||||
__builtin_va_end(ap);
|
||||
return ll;
|
||||
@ -24,10 +25,11 @@ double t2(int i, ...) {
|
||||
// APCS-GNU: t2
|
||||
__builtin_va_list ap;
|
||||
__builtin_va_start(ap, i);
|
||||
// AAPCS: add i32 %{{.*}} 7
|
||||
// AAPCS: and i32 %{{.*}} -8
|
||||
// APCS-GNU-NOT: add i32 %{{.*}} 7
|
||||
// APCS-GNU-NOT: and i32 %{{.*}} -8
|
||||
// AAPCS: [[ADD:%.*]] = getelementptr inbounds i8, ptr %argp.cur, i32 7
|
||||
// AAPCS = call ptr @llvm.ptrmask.p0.i32(ptr [[ADD]], i32 -8)
|
||||
|
||||
// APCS-GNU-NOT: getelementptr {{.*}}, i32 7
|
||||
// APCS-GNU-NOT: llvm.ptrmask.p0
|
||||
double ll = __builtin_va_arg(ap, double);
|
||||
__builtin_va_end(ap);
|
||||
return ll;
|
||||
|
||||
@ -41,10 +41,8 @@ struct aligned_bigstruct simple_aligned_struct(void) {
|
||||
// CHECK-LABEL: define{{.*}} void @simple_aligned_struct(ptr noalias sret(%struct.aligned_bigstruct) align 8 %agg.result)
|
||||
return va_arg(the_list, struct aligned_bigstruct);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 16
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 8 %agg.result, ptr align 8 [[CUR_ALIGNED]], i32 16, i1 false)
|
||||
@ -55,10 +53,8 @@ double simple_double(void) {
|
||||
// CHECK-LABEL: define{{.*}} double @simple_double
|
||||
return va_arg(the_list, double);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 8
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: [[RESULT:%[a-z0-9._]+]] = load double, ptr [[CUR_ALIGNED]]
|
||||
@ -110,10 +106,8 @@ underaligned_long_long underaligned_long_long_test(void) {
|
||||
// CHECK-LABEL: define{{.*}} i64 @underaligned_long_long_test()
|
||||
return va_arg(the_list, underaligned_long_long);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 8
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: [[RESULT:%[a-z0-9._]+]] = load i64, ptr [[CUR_ALIGNED]]
|
||||
@ -125,10 +119,8 @@ overaligned_long_long overaligned_long_long_test(void) {
|
||||
// CHECK-LABEL: define{{.*}} i64 @overaligned_long_long_test()
|
||||
return va_arg(the_list, overaligned_long_long);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 8
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: [[RESULT:%[a-z0-9._]+]] = load i64, ptr [[CUR_ALIGNED]]
|
||||
@ -196,10 +188,8 @@ overaligned_long_long_struct overaligned_long_long_struct_test(void) {
|
||||
// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_test(ptr noalias sret(%struct.overaligned_long_long_struct) align 16 %agg.result)
|
||||
return va_arg(the_list, overaligned_long_long_struct);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 16
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 16 %agg.result, ptr align 8 [[CUR_ALIGNED]], i32 16, i1 false)
|
||||
@ -232,10 +222,8 @@ overaligned_int_struct_member overaligned_int_struct_member_test(void) {
|
||||
// CHECK-LABEL: define{{.*}} void @overaligned_int_struct_member_test(ptr noalias sret(%struct.overaligned_int_struct_member) align 16 %agg.result)
|
||||
return va_arg(the_list, overaligned_int_struct_member);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 16
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 16 %agg.result, ptr align 8 [[CUR_ALIGNED]], i32 16, i1 false)
|
||||
@ -262,10 +250,8 @@ overaligned_long_long_struct_member overaligned_long_long_struct_member_test(voi
|
||||
// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_member_test(ptr noalias sret(%struct.overaligned_long_long_struct_member) align 16 %agg.result)
|
||||
return va_arg(the_list, overaligned_long_long_struct_member);
|
||||
// CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4
|
||||
// CHECK: [[CUR_INT:%[a-z0-9._]+]] = ptrtoint ptr [[CUR]] to i32
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = add i32 [[CUR_INT]], 7
|
||||
// CHECK: [[CUR_INT_ALIGNED:%[a-z0-9._]+]] = and i32 [[CUR_INT_ADD]], -8
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = inttoptr i32 [[CUR_INT_ALIGNED]] to ptr
|
||||
// CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7
|
||||
// CHECK: [[CUR_ALIGNED:%[a-z0-9._]+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[CUR_INT_ADD]], i32 -8)
|
||||
// CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR_ALIGNED]], i32 16
|
||||
// CHECK: store ptr [[NEXT]], ptr @the_list, align 4
|
||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 16 %agg.result, ptr align 8 [[CUR_ALIGNED]], i32 16, i1 false)
|
||||
|
||||
@ -94,8 +94,9 @@ double test_5c(__char5 *in) {
|
||||
double varargs_vec_9c(int fixed, ...) {
|
||||
// CHECK: varargs_vec_9c
|
||||
// CHECK: alloca <9 x i8>, align 16
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
va_list ap;
|
||||
double sum = fixed;
|
||||
@ -153,8 +154,9 @@ double test_3s(__short3 *in) {
|
||||
double varargs_vec_5s(int fixed, ...) {
|
||||
// CHECK: varargs_vec_5s
|
||||
// CHECK: alloca <5 x i16>, align 16
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
va_list ap;
|
||||
double sum = fixed;
|
||||
@ -174,8 +176,9 @@ double test_5s(__short5 *in) {
|
||||
double varargs_vec_3i(int fixed, ...) {
|
||||
// CHECK: varargs_vec_3i
|
||||
// CHECK: alloca <3 x i32>, align 16
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
va_list ap;
|
||||
double sum = fixed;
|
||||
@ -244,8 +247,11 @@ double varargs_vec(int fixed, ...) {
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_CUR:%.*]], i64 8
|
||||
sum = sum + c5.x + c5.y;
|
||||
__char9 c9 = va_arg(ap, __char9);
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
|
||||
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
sum = sum + c9.x + c9.y;
|
||||
__char19 c19 = va_arg(ap, __char19);
|
||||
@ -256,13 +262,17 @@ double varargs_vec(int fixed, ...) {
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_CUR:%.*]], i64 8
|
||||
sum = sum + s3.x + s3.y;
|
||||
__short5 s5 = va_arg(ap, __short5);
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
sum = sum + s5.x + s5.y;
|
||||
__int3 i3 = va_arg(ap, __int3);
|
||||
// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
|
||||
// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to ptr
|
||||
|
||||
// CHECK: [[AP:%.*]] = load ptr, ptr %ap, align 8
|
||||
// CHECK: [[AP_ADD:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 15
|
||||
// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[AP_ADD]], i64 -16)
|
||||
// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i64 16
|
||||
sum = sum + i3.x + i3.y;
|
||||
__int5 i5 = va_arg(ap, __int5);
|
||||
|
||||
@ -707,10 +707,8 @@ int32x4_t test_hva(int n, ...) {
|
||||
|
||||
// HVA is not indirect, so occupies its full 16 bytes on the stack. but it
|
||||
// must be properly aligned.
|
||||
// CHECK-LE: [[ALIGN0:%.*]] = ptrtoint ptr [[CURLIST]] to i64
|
||||
// CHECK-LE: [[ALIGN1:%.*]] = add i64 [[ALIGN0]], 15
|
||||
// CHECK-LE: [[ALIGN2:%.*]] = and i64 [[ALIGN1]], -16
|
||||
// CHECK-LE: [[ALIGNED_LIST:%.*]] = inttoptr i64 [[ALIGN2]] to ptr
|
||||
// CHECK-LE: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[CURLIST]], i32 15
|
||||
// CHECK-LE: [[ALIGNED_LIST:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[GEP]], i64 -16)
|
||||
|
||||
// CHECK-LE: [[NEXTLIST:%.*]] = getelementptr inbounds i8, ptr [[ALIGNED_LIST]], i64 32
|
||||
// CHECK-LE: store ptr [[NEXTLIST]], ptr [[THELIST]]
|
||||
@ -752,11 +750,9 @@ float32x3_t test_hva_v3(int n, ...) {
|
||||
|
||||
// HVA is not indirect, so occupies its full 16 bytes on the stack. but it
|
||||
// must be properly aligned.
|
||||
// CHECK-LE: [[ALIGN0:%.*]] = ptrtoint ptr [[CURLIST]] to i64
|
||||
// CHECK-LE: [[ALIGN1:%.*]] = add i64 [[ALIGN0]], 15
|
||||
// CHECK-LE: [[ALIGN2:%.*]] = and i64 [[ALIGN1]], -16
|
||||
// CHECK-LE: [[ALIGNED_LIST:%.*]] = inttoptr i64 [[ALIGN2]] to ptr
|
||||
|
||||
// CHECK-LE: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[CURLIST]], i32 15
|
||||
// CHECK-LE: [[ALIGNED_LIST:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[GEP]], i64 -16)
|
||||
// CHECK-LE: [[NEXTLIST:%.*]] = getelementptr inbounds i8, ptr [[ALIGNED_LIST]], i64 64
|
||||
// CHECK-LE: store ptr [[NEXTLIST]], ptr [[THELIST]]
|
||||
|
||||
|
||||
@ -28,11 +28,8 @@ typedef struct {
|
||||
long long test_longlong(OneLongLong input, va_list *mylist) {
|
||||
// CHECK-LABEL: define{{.*}} i64 @test_longlong(i64 %input
|
||||
// CHECK: [[STARTPTR:%.*]] = load ptr, ptr %mylist
|
||||
// CHECK: [[START:%.*]] = ptrtoint ptr [[STARTPTR]] to i32
|
||||
|
||||
// CHECK: [[ALIGN_TMP:%.*]] = add i32 [[START]], 7
|
||||
// CHECK: [[ALIGNED:%.*]] = and i32 [[ALIGN_TMP]], -8
|
||||
// CHECK: [[ALIGNED_ADDR:%.*]] = inttoptr i32 [[ALIGNED]] to ptr
|
||||
// CHECK: [[ALIGN_TMP:%.+]] = getelementptr inbounds i8, ptr [[STARTPTR]], i32 7
|
||||
// CHECK: [[ALIGNED_ADDR:%.+]] = tail call ptr @llvm.ptrmask.p0.i32(ptr nonnull [[ALIGN_TMP]], i32 -8)
|
||||
// CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[ALIGNED_ADDR]], i32 8
|
||||
// CHECK: store ptr [[NEXT]], ptr %mylist
|
||||
|
||||
|
||||
@ -85,10 +85,11 @@ typedef struct {
|
||||
OddlySizedStruct return_oddly_sized_struct() {}
|
||||
|
||||
// CHECK: define{{.*}} <4 x float> @test_va_arg_vec(ptr noundef %l)
|
||||
// CHECK: [[ALIGN_TMP:%.*]] = add i32 {{%.*}}, 15
|
||||
// CHECK: [[ALIGNED:%.*]] = and i32 [[ALIGN_TMP]], -16
|
||||
// CHECK: [[ALIGNED_I8:%.*]] = inttoptr i32 [[ALIGNED]] to ptr
|
||||
// CHECK: load <4 x float>, ptr [[ALIGNED_I8]], align 16
|
||||
|
||||
|
||||
// CHECK: [[GEP_ALIGN:%.+]] = getelementptr inbounds i8, ptr {{%.*}}, i32 15
|
||||
// CHECK: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[GEP_ALIGN]], i32 -16)
|
||||
// CHECK: load <4 x float>, ptr [[ALIGNED]], align 16
|
||||
float32x4_t test_va_arg_vec(__builtin_va_list l) {
|
||||
return __builtin_va_arg(l, float32x4_t);
|
||||
}
|
||||
|
||||
@ -66,10 +66,8 @@ long long test_i64(char *fmt, ...) {
|
||||
//
|
||||
// i64 is 8-byte aligned, while this is within O32's stack alignment there's no
|
||||
// guarantee that the offset is still 8-byte aligned after earlier reads.
|
||||
// O32: [[TMP1:%.+]] = ptrtoint ptr [[AP_CUR]] to i32
|
||||
// O32: [[TMP2:%.+]] = add i32 [[TMP1]], 7
|
||||
// O32: [[TMP3:%.+]] = and i32 [[TMP2]], -8
|
||||
// O32: [[AP_CUR:%.+]] = inttoptr i32 [[TMP3]] to ptr
|
||||
// O32: [[TMP1:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], i32 7
|
||||
// O32: [[AP_CUR:%.+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP1]], i32 -8)
|
||||
//
|
||||
// ALL: [[AP_NEXT:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], [[$INTPTR_T]] 8
|
||||
// ALL: store ptr [[AP_NEXT]], ptr %va, align [[$PTRALIGN]]
|
||||
@ -135,15 +133,16 @@ int test_v4i32(char *fmt, ...) {
|
||||
//
|
||||
// Vectors are 16-byte aligned, however the O32 ABI has a maximum alignment of
|
||||
// 8-bytes since the base of the stack is 8-byte aligned.
|
||||
// O32: [[TMP1:%.+]] = ptrtoint ptr [[AP_CUR]] to i32
|
||||
// O32: [[TMP2:%.+]] = add i32 [[TMP1]], 7
|
||||
// O32: [[TMP3:%.+]] = and i32 [[TMP2]], -8
|
||||
// O32: [[AP_CUR:%.+]] = inttoptr i32 [[TMP3]] to ptr
|
||||
//
|
||||
// NEW: [[TMP1:%.+]] = ptrtoint ptr [[AP_CUR]] to [[$INTPTR_T]]
|
||||
// NEW: [[TMP2:%.+]] = add [[$INTPTR_T]] [[TMP1]], 15
|
||||
// NEW: [[TMP3:%.+]] = and [[$INTPTR_T]] [[TMP2]], -16
|
||||
// NEW: [[AP_CUR:%.+]] = inttoptr [[$INTPTR_T]] [[TMP3]] to ptr
|
||||
|
||||
// O32: [[TMP1:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], i32 7
|
||||
// O32: [[AP_CUR:%.+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP1]], i32 -8)
|
||||
|
||||
// N32: [[TMP1:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], i32 15
|
||||
// N32: [[AP_CUR:%.+]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP1]], i32 -16)
|
||||
|
||||
// N64: [[TMP1:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], i32 15
|
||||
// N64: [[AP_CUR:%.+]] = call ptr @llvm.ptrmask.p0.i64(ptr [[TMP1]], i64 -16)
|
||||
|
||||
//
|
||||
// ALL: [[AP_NEXT:%.+]] = getelementptr inbounds i8, ptr [[AP_CUR]], [[$INTPTR_T]] 16
|
||||
// ALL: store ptr [[AP_NEXT]], ptr %va, align [[$PTRALIGN]]
|
||||
|
||||
@ -9,10 +9,8 @@
|
||||
|
||||
// CHECK-LABEL: define dso_local void @testm128
|
||||
// CHECK-LABEL: %argp.cur = load ptr, ptr %args, align 4
|
||||
// CHECK-NEXT: %0 = ptrtoint ptr %argp.cur to i32
|
||||
// CHECK-NEXT: %1 = add i32 %0, 15
|
||||
// CHECK-NEXT: %2 = and i32 %1, -16
|
||||
// CHECK-NEXT: %argp.cur.aligned = inttoptr i32 %2 to ptr
|
||||
// CHECK-NEXT: %0 = getelementptr inbounds i8, ptr %argp.cur, i32 15
|
||||
// CHECK-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i32(ptr %0, i32 -16)
|
||||
void testm128(int argCount, ...) {
|
||||
__m128 res;
|
||||
__builtin_va_list args;
|
||||
@ -23,10 +21,8 @@ void testm128(int argCount, ...) {
|
||||
|
||||
// CHECK-LABEL: define dso_local void @testm256
|
||||
// CHECK-LABEL: %argp.cur = load ptr, ptr %args, align 4
|
||||
// CHECK-NEXT: %0 = ptrtoint ptr %argp.cur to i32
|
||||
// CHECK-NEXT: %1 = add i32 %0, 31
|
||||
// CHECK-NEXT: %2 = and i32 %1, -32
|
||||
// CHECK-NEXT: %argp.cur.aligned = inttoptr i32 %2 to ptr
|
||||
// CHECK-NEXT: %0 = getelementptr inbounds i8, ptr %argp.cur, i32 31
|
||||
// CHECK-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i32(ptr %0, i32 -32)
|
||||
void testm256(int argCount, ...) {
|
||||
__m256 res;
|
||||
__builtin_va_list args;
|
||||
@ -37,10 +33,8 @@ void testm256(int argCount, ...) {
|
||||
|
||||
// CHECK-LABEL: define dso_local void @testm512
|
||||
// CHECK-LABEL: %argp.cur = load ptr, ptr %args, align 4
|
||||
// CHECK-NEXT: %0 = ptrtoint ptr %argp.cur to i32
|
||||
// CHECK-NEXT: %1 = add i32 %0, 63
|
||||
// CHECK-NEXT: %2 = and i32 %1, -64
|
||||
// CHECK-NEXT: %argp.cur.aligned = inttoptr i32 %2 to ptr
|
||||
// CHECK-NEXT: %0 = getelementptr inbounds i8, ptr %argp.cur, i32 63
|
||||
// CHECK-NEXT: %argp.cur.aligned = call ptr @llvm.ptrmask.p0.i32(ptr %0, i32 -64)
|
||||
void testm512(int argCount, ...) {
|
||||
__m512 res;
|
||||
__builtin_va_list args;
|
||||
|
||||
@ -200,7 +200,7 @@ void TakesVarargs(int i, ...) {
|
||||
// WIN64: store i92 %[[LOADV1]], ptr
|
||||
|
||||
// WIN32: %[[CUR1:.+]] = load ptr, ptr %[[ARGS]]
|
||||
// WIN32: %[[NEXT1:.+]] = getelementptr inbounds i8, ptr %[[CUR1]], i32 16
|
||||
// WIN32: %[[NEXT1:.+]] = getelementptr inbounds i8, ptr %[[CUR1]], i32 16
|
||||
// WIN32: store ptr %[[NEXT1]], ptr %[[ARGS]]
|
||||
// WIN32: %[[LOADV1:.+]] = load i92, ptr %[[CUR1]]
|
||||
// WIN32: store i92 %[[LOADV1]], ptr
|
||||
@ -289,18 +289,16 @@ void TakesVarargs(int i, ...) {
|
||||
// LIN64: %[[AD5:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], ptr %[[ARGS]]
|
||||
// LIN64: %[[OFAA_P4:.+]] = getelementptr inbounds %struct.__va_list_tag, ptr %[[AD5]], i32 0, i32 2
|
||||
// LIN64: %[[OFAA:.+]] = load ptr, ptr %[[OFAA_P4]]
|
||||
// LIN64: %[[TOINT:.+]] = ptrtoint ptr %[[OFAA]] to i64
|
||||
// LIN64: %[[ADD:.+]] = add i64 %[[TOINT]], 31
|
||||
// LIN64: %[[AND:.+]] = and i64 %[[ADD]], -32
|
||||
// LIN64: %[[OFAA_ALIGNED:.+]] = inttoptr i64 %[[AND]] to ptr
|
||||
|
||||
// LIN64: [[OFAA_GEP:%.*]] = getelementptr inbounds i8, ptr %[[OFAA]], i32 31
|
||||
// LIN64: %[[OFAA_ALIGNED:.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[OFAA_GEP]], i64 -32)
|
||||
// LIN64: %[[LOADV5:.+]] = load <8 x i32>, ptr %[[OFAA_ALIGNED]]
|
||||
// LIN64: store <8 x i32> %[[LOADV5]], ptr
|
||||
|
||||
// LIN32: %[[CUR5:.+]] = load ptr, ptr %[[ARGS]]
|
||||
// LIN32: %[[TOINT:.+]] = ptrtoint ptr %[[CUR5]] to i32
|
||||
// LIN32: %[[ADD:.+]] = add i32 %[[TOINT]], 31
|
||||
// LIN32: %[[AND:.+]] = and i32 %[[ADD]], -32
|
||||
// LIN32: %[[CUR5_ALIGNED:.+]] = inttoptr i32 %[[AND]] to ptr
|
||||
|
||||
// LIN32: [[GEP_CUR5:%.*]] = getelementptr inbounds i8, ptr %[[CUR5]], i32 31
|
||||
// LIN32: %[[CUR5_ALIGNED:.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[GEP_CUR5]], i32 -32)
|
||||
// LIN32: %[[NEXT5:.+]] = getelementptr inbounds i8, ptr %[[CUR5_ALIGNED]], i32 32
|
||||
// LIN32: store ptr %[[NEXT5]], ptr %[[ARGS]]
|
||||
// LIN32: %[[LOADV5:.+]] = load <8 x i32>, ptr %[[CUR5_ALIGNED]]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user