[clang] 8e00934 - clang: Use ptrmask for pointer alignment

Matt Arsenault via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 16 04:16:49 PDT 2023


Author: Matt Arsenault
Date: 2023-03-16T07:16:41-04:00
New Revision: 8e009348e8a2e9c4577538eba6ca5c6cb286776f

URL: https://github.com/llvm/llvm-project/commit/8e009348e8a2e9c4577538eba6ca5c6cb286776f
DIFF: https://github.com/llvm/llvm-project/commit/8e009348e8a2e9c4577538eba6ca5c6cb286776f.diff

LOG: clang: Use ptrmask for pointer alignment

Avoid using ptrtoint/inttoptr.

Added: 
    

Modified: 
    clang/lib/CodeGen/TargetInfo.cpp
    clang/test/CodeGen/PowerPC/aix-altivec-vaargs.c
    clang/test/CodeGen/PowerPC/ppc-varargs-struct.c
    clang/test/CodeGen/PowerPC/ppc64-align-struct.c
    clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
    clang/test/CodeGen/RISCV/riscv32-vararg.c
    clang/test/CodeGen/RISCV/riscv64-vararg.c
    clang/test/CodeGen/WebAssembly/wasm-varargs.c
    clang/test/CodeGen/X86/x86_32-arguments-darwin.c
    clang/test/CodeGen/X86/x86_64-arguments.c
    clang/test/CodeGen/arm-abi-vector.c
    clang/test/CodeGen/arm-vaarg-align.c
    clang/test/CodeGen/arm-varargs.c
    clang/test/CodeGen/arm64-abi-vector.c
    clang/test/CodeGen/arm64-arguments.c
    clang/test/CodeGen/arm64_32-vaarg.c
    clang/test/CodeGen/armv7k-abi.c
    clang/test/CodeGen/mips-varargs.c
    clang/test/CodeGen/x86_32-align-linux.c
    clang/test/CodeGenCXX/ext-int.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 38211533adc69..2d3d5368ace2b 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -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,

diff  --git a/clang/test/CodeGen/PowerPC/aix-altivec-vaargs.c b/clang/test/CodeGen/PowerPC/aix-altivec-vaargs.c
index 657d83454b0fc..03182423a422c 100644
--- a/clang/test/CodeGen/PowerPC/aix-altivec-vaargs.c
+++ b/clang/test/CodeGen/PowerPC/aix-altivec-vaargs.c
@@ -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
 
 

diff  --git a/clang/test/CodeGen/PowerPC/ppc-varargs-struct.c b/clang/test/CodeGen/PowerPC/ppc-varargs-struct.c
index 6b69975870835..c8d54dd8e418f 100644
--- a/clang/test/CodeGen/PowerPC/ppc-varargs-struct.c
+++ b/clang/test/CodeGen/PowerPC/ppc-varargs-struct.c
@@ -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

diff  --git a/clang/test/CodeGen/PowerPC/ppc64-align-struct.c b/clang/test/CodeGen/PowerPC/ppc64-align-struct.c
index b0d14546566cb..2476c7149d076 100644
--- a/clang/test/CodeGen/PowerPC/ppc64-align-struct.c
+++ b/clang/test/CodeGen/PowerPC/ppc64-align-struct.c
@@ -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)

diff  --git a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
index 50b3c0451bd80..53cb0dbd1d610 100644
--- a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
+++ b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
@@ -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)

diff  --git a/clang/test/CodeGen/RISCV/riscv32-vararg.c b/clang/test/CodeGen/RISCV/riscv32-vararg.c
index 9aeeb12b91f9f..02b1ed38e2655 100644
--- a/clang/test/CodeGen/RISCV/riscv32-vararg.c
+++ b/clang/test/CodeGen/RISCV/riscv32-vararg.c
@@ -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, ...) {

diff  --git a/clang/test/CodeGen/RISCV/riscv64-vararg.c b/clang/test/CodeGen/RISCV/riscv64-vararg.c
index 606b322daf6ca..26261f0095ac9 100644
--- a/clang/test/CodeGen/RISCV/riscv64-vararg.c
+++ b/clang/test/CodeGen/RISCV/riscv64-vararg.c
@@ -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, ...) {

diff  --git a/clang/test/CodeGen/WebAssembly/wasm-varargs.c b/clang/test/CodeGen/WebAssembly/wasm-varargs.c
index 3c743692e0942..da22ad6a1b2e9 100644
--- a/clang/test/CodeGen/WebAssembly/wasm-varargs.c
+++ b/clang/test/CodeGen/WebAssembly/wasm-varargs.c
@@ -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
 //

diff  --git a/clang/test/CodeGen/X86/x86_32-arguments-darwin.c b/clang/test/CodeGen/X86/x86_32-arguments-darwin.c
index f4db6b27dabbe..ae385c4121dee 100644
--- a/clang/test/CodeGen/X86/x86_32-arguments-darwin.c
+++ b/clang/test/CodeGen/X86/x86_32-arguments-darwin.c
@@ -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;

diff  --git a/clang/test/CodeGen/X86/x86_64-arguments.c b/clang/test/CodeGen/X86/x86_64-arguments.c
index d42a7d7cfdeac..fe31bfa9e778b 100644
--- a/clang/test/CodeGen/X86/x86_64-arguments.c
+++ b/clang/test/CodeGen/X86/x86_64-arguments.c
@@ -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, ...) {

diff  --git a/clang/test/CodeGen/arm-abi-vector.c b/clang/test/CodeGen/arm-abi-vector.c
index 43620f8550033..7f0cc4bcb0cd8 100644
--- a/clang/test/CodeGen/arm-abi-vector.c
+++ b/clang/test/CodeGen/arm-abi-vector.c
@@ -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;

diff  --git a/clang/test/CodeGen/arm-vaarg-align.c b/clang/test/CodeGen/arm-vaarg-align.c
index 2270c8b4f971e..410c1ebd5d146 100644
--- a/clang/test/CodeGen/arm-vaarg-align.c
+++ b/clang/test/CodeGen/arm-vaarg-align.c
@@ -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;

diff  --git a/clang/test/CodeGen/arm-varargs.c b/clang/test/CodeGen/arm-varargs.c
index c8a8899a967de..17330262e6ad6 100644
--- a/clang/test/CodeGen/arm-varargs.c
+++ b/clang/test/CodeGen/arm-varargs.c
@@ -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)

diff  --git a/clang/test/CodeGen/arm64-abi-vector.c b/clang/test/CodeGen/arm64-abi-vector.c
index 2063e46c414a8..81e42315c883b 100644
--- a/clang/test/CodeGen/arm64-abi-vector.c
+++ b/clang/test/CodeGen/arm64-abi-vector.c
@@ -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);

diff  --git a/clang/test/CodeGen/arm64-arguments.c b/clang/test/CodeGen/arm64-arguments.c
index 13728e43dff69..8bc48795c690c 100644
--- a/clang/test/CodeGen/arm64-arguments.c
+++ b/clang/test/CodeGen/arm64-arguments.c
@@ -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]]
 

diff  --git a/clang/test/CodeGen/arm64_32-vaarg.c b/clang/test/CodeGen/arm64_32-vaarg.c
index ec2fcb128f3a4..9fbcf88ecfdcc 100644
--- a/clang/test/CodeGen/arm64_32-vaarg.c
+++ b/clang/test/CodeGen/arm64_32-vaarg.c
@@ -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
 

diff  --git a/clang/test/CodeGen/armv7k-abi.c b/clang/test/CodeGen/armv7k-abi.c
index 696e9ab994621..e070d5a9c7041 100644
--- a/clang/test/CodeGen/armv7k-abi.c
+++ b/clang/test/CodeGen/armv7k-abi.c
@@ -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);
 }

diff  --git a/clang/test/CodeGen/mips-varargs.c b/clang/test/CodeGen/mips-varargs.c
index e8d11587fe681..052aedd1cd1e2 100644
--- a/clang/test/CodeGen/mips-varargs.c
+++ b/clang/test/CodeGen/mips-varargs.c
@@ -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]]

diff  --git a/clang/test/CodeGen/x86_32-align-linux.c b/clang/test/CodeGen/x86_32-align-linux.c
index a58e1ece2e409..d383a2c0a92ff 100644
--- a/clang/test/CodeGen/x86_32-align-linux.c
+++ b/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 @@ 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;

diff  --git a/clang/test/CodeGenCXX/ext-int.cpp b/clang/test/CodeGenCXX/ext-int.cpp
index 86c566f903e32..7676dec791f3f 100644
--- a/clang/test/CodeGenCXX/ext-int.cpp
+++ b/clang/test/CodeGenCXX/ext-int.cpp
@@ -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]]


        


More information about the cfe-commits mailing list