Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -295,17 +295,13 @@ 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, Index: clang/test/CodeGen/PowerPC/ppc-varargs-struct.c =================================================================== --- clang/test/CodeGen/PowerPC/ppc-varargs-struct.c +++ clang/test/CodeGen/PowerPC/ppc-varargs-struct.c @@ -37,10 +37,8 @@ // 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 @@ // 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 Index: clang/test/CodeGen/x86_32-align-linux.c =================================================================== --- clang/test/CodeGen/x86_32-align-linux.c +++ clang/test/CodeGen/x86_32-align-linux.c @@ -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 @@ // 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 @@ // 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;