durin42 updated this revision to Diff 529616.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119271/new/

https://reviews.llvm.org/D119271

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/test/CodeGen/alloc-align-attr.c
  clang/test/CodeGen/alloc-fns-alignment.c
  clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
  clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
  clang/test/CodeGenCXX/align-avx-complete-objects.cpp
  clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
  clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp

Index: clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
===================================================================
--- clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
+++ clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
@@ -27,10 +27,10 @@
 struct OVERALIGNED A { A(); int n[128]; };
 
 // CHECK-LABEL: define {{.*}} @_Z2a0v()
-// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 32)
+// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 allocalign noundef 32)
 // CHECK: call void @_ZdlPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 32)
 // CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"()
-// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef 512, i64 noundef 32)
+// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef 512, i64 allocalign noundef 32)
 // CHECK-MS: cleanuppad
 // CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(ptr allocptr noundef %[[ALLOC]], i64 noundef 32)
 void *a0() { return new A; }
@@ -39,13 +39,13 @@
 // The size is known.
 //
 // CHECK-LABEL: define {{.*}} @_Z2a1l(
-// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 noundef 32)
+// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 allocalign noundef 32)
 // No array cookie.
 // CHECK-NOT: store
 // CHECK: invoke void @_ZN1AC1Ev(
 // CHECK: call void @_ZdaPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 32)
 // CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"(
-// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef %{{.*}}, i64 noundef 32)
+// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef %{{.*}}, i64 allocalign noundef 32)
 // No array cookie.
 // CHECK-MS-NOT: store
 // CHECK-MS: invoke noundef ptr @"??0A@@QEAA@XZ"(
@@ -84,7 +84,7 @@
 void *b0() { return new B; }
 
 // CHECK-LABEL: define {{.*}} @_Z2b1l(
-// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 noundef 32)
+// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 allocalign noundef 32)
 // No array cookie.
 // CHECK-NOT: store
 // CHECK: invoke void @_ZN1BC1Ev(
@@ -169,7 +169,7 @@
 
 #ifndef UNALIGNED
 // CHECK-LABEL: define {{.*}} @_Z2e0v(
-// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 4 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 4)
+// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 4 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 allocalign noundef 4)
 // CHECK: call void @_ZdlPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 4)
 void *e0() { return new (std::align_val_t(4)) A; }
 
Index: clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
===================================================================
--- clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
+++ clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
@@ -47,7 +47,7 @@
 
 // CHECK-LABEL: define{{.*}} void @test_aligned_alloc(
 extern "C" void test_aligned_alloc() {
-  // CHECK: call noalias noundef nonnull align 4 ptr @_ZnwmSt11align_val_t(i64 noundef 4, i64 noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+  // CHECK: call noalias noundef nonnull align 4 ptr @_ZnwmSt11align_val_t(i64 noundef 4, i64 allocalign noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
   // CHECK: call void @_ZdlPvSt11align_val_t({{.*}}, i64 noundef 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
   __builtin_operator_delete(__builtin_operator_new(4, std::align_val_t(4)), std::align_val_t(4));
 }
Index: clang/test/CodeGenCXX/align-avx-complete-objects.cpp
===================================================================
--- clang/test/CodeGenCXX/align-avx-complete-objects.cpp
+++ clang/test/CodeGenCXX/align-avx-complete-objects.cpp
@@ -18,7 +18,7 @@
 
 // CHECK: [[R:%.*]] = alloca <8 x float>, align 32
 // PRE17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm(i64 noundef 32)
-// CXX17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 32, i64 noundef 32)
+// CXX17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 32, i64 allocalign noundef 32)
 // CHECK-NEXT:  store ptr [[CALL]], ptr [[P:%.*]], align 8
 // CHECK-NEXT:  [[ONE:%.*]] = load ptr, ptr [[P]], align 8
 // CHECK-NEXT:  [[TWO:%.*]] = load volatile <8 x float>, ptr [[ONE]], align 16
@@ -50,7 +50,7 @@
 
 // CHECK: [[R:%.*]] = alloca <8 x float>, align 32
 // PRE17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm(i64 noundef 32)
-// CXX17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 32, i64 noundef 32)
+// CXX17-NEXT:  [[CALL:%.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 32, i64 allocalign noundef 32)
 // CHECK-NEXT:  store ptr [[CALL]], ptr [[P:%.*]], align 8
 // CHECK-NEXT:  [[ONE:%.*]] = load ptr, ptr [[P]], align 8
 // CHECK-NEXT:  [[TWO:%.*]] = load volatile <8 x float>, ptr [[ONE]], align 32
Index: clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
===================================================================
--- clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
+++ clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
@@ -8,9 +8,7 @@
 // CHECK-NEXT:    [[ALIGN_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store i32 [[ALIGN:%.*]], ptr [[ALIGN_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ALIGN_ADDR]], align 4
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @alloc(i32 noundef [[TMP0]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @alloc(i32 allocalign noundef [[TMP0]])
 // CHECK-NEXT:    ret void
 //
 void t0(int align) {
@@ -20,8 +18,7 @@
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[ALIGN_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store i32 [[ALIGN:%.*]], ptr [[ALIGN_ADDR]], align 4
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @alloc(i32 noundef 7)
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 7) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @alloc(i32 allocalign noundef 7)
 // CHECK-NEXT:    ret void
 //
 void t1(int align) {
@@ -31,7 +28,7 @@
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[ALIGN_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store i32 [[ALIGN:%.*]], ptr [[ALIGN_ADDR]], align 4
-// CHECK-NEXT:    [[CALL:%.*]] = call align 8 ptr @alloc(i32 noundef 8)
+// CHECK-NEXT:    [[CALL:%.*]] = call align 8 ptr @alloc(i32 allocalign noundef 8)
 // CHECK-NEXT:    ret void
 //
 void t2(int align) {
Index: clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
===================================================================
--- clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
+++ clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
@@ -98,7 +98,7 @@
 // CHECK-NOSANITIZE-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NOSANITIZE-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
 // CHECK-NOSANITIZE-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-NOSANITIZE-NEXT:    [[CALL:%.*]] = call noundef align 128 ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef 128)
+// CHECK-NOSANITIZE-NEXT:    [[CALL:%.*]] = call noundef align 128 ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 allocalign noundef 128)
 // CHECK-NOSANITIZE-NEXT:    ret ptr [[CALL]]
 //
 // CHECK-SANITIZE-NORECOVER-LABEL: define dso_local noundef ptr @_Z6callerPPc
@@ -107,17 +107,7 @@
 // CHECK-SANITIZE-NORECOVER-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-SANITIZE-NORECOVER-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
 // CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef 128)
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 127
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-NORECOVER-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[HANDLER_ALIGNMENT_ASSUMPTION:%.*]], !prof [[PROF3]], !nosanitize !2
-// CHECK-SANITIZE-NORECOVER:       handler.alignment_assumption:
-// CHECK-SANITIZE-NORECOVER-NEXT:    call void @__ubsan_handle_alignment_assumption_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP1]], i64 128, i64 0) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-NORECOVER-NEXT:    unreachable, !nosanitize !2
-// CHECK-SANITIZE-NORECOVER:       cont:
-// CHECK-SANITIZE-NORECOVER-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 128) ]
+// CHECK-SANITIZE-NORECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 allocalign noundef 128)
 // CHECK-SANITIZE-NORECOVER-NEXT:    ret ptr [[CALL]]
 //
 // CHECK-SANITIZE-RECOVER-LABEL: define dso_local noundef ptr @_Z6callerPPc
@@ -126,17 +116,7 @@
 // CHECK-SANITIZE-RECOVER-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-SANITIZE-RECOVER-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
 // CHECK-SANITIZE-RECOVER-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef 128)
-// CHECK-SANITIZE-RECOVER-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-RECOVER-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 127
-// CHECK-SANITIZE-RECOVER-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-RECOVER-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-RECOVER-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[HANDLER_ALIGNMENT_ASSUMPTION:%.*]], !prof [[PROF3]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER:       handler.alignment_assumption:
-// CHECK-SANITIZE-RECOVER-NEXT:    call void @__ubsan_handle_alignment_assumption(ptr @[[GLOB3:[0-9]+]], i64 [[TMP1]], i64 128, i64 0) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER-NEXT:    br label [[CONT]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER:       cont:
-// CHECK-SANITIZE-RECOVER-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 128) ]
+// CHECK-SANITIZE-RECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 allocalign noundef 128)
 // CHECK-SANITIZE-RECOVER-NEXT:    ret ptr [[CALL]]
 //
 // CHECK-SANITIZE-TRAP-LABEL: define dso_local noundef ptr @_Z6callerPPc
@@ -145,17 +125,7 @@
 // CHECK-SANITIZE-TRAP-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-SANITIZE-TRAP-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
 // CHECK-SANITIZE-TRAP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-TRAP-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef 128)
-// CHECK-SANITIZE-TRAP-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-TRAP-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 127
-// CHECK-SANITIZE-TRAP-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-TRAP-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-TRAP-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize !2
-// CHECK-SANITIZE-TRAP:       trap:
-// CHECK-SANITIZE-TRAP-NEXT:    call void @llvm.ubsantrap(i8 23) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-TRAP-NEXT:    unreachable, !nosanitize !2
-// CHECK-SANITIZE-TRAP:       cont:
-// CHECK-SANITIZE-TRAP-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 128) ]
+// CHECK-SANITIZE-TRAP-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 allocalign noundef 128)
 // CHECK-SANITIZE-TRAP-NEXT:    ret ptr [[CALL]]
 //
 char **caller(char **x) {
Index: clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
===================================================================
--- clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
+++ clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
@@ -82,78 +82,19 @@
   return x;
 }
 
-// CHECK-SANITIZE-NORECOVER-LABEL: define dso_local noundef ptr @_Z6callerPPcm
-// CHECK-SANITIZE-NORECOVER-SAME: (ptr noundef [[X:%.*]], i64 noundef [[ALIGNMENT:%.*]]) #[[ATTR0]] {
-// CHECK-SANITIZE-NORECOVER-NEXT:  entry:
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[ALIGNMENT_ADDR:%.*]] = alloca i64, align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    store i64 [[ALIGNMENT]], ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP1:%.*]] = load i64, ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef [[TMP1]])
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP2:%.*]] = sub i64 [[TMP1]], 1
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[TMP2]]
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-NORECOVER-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-NORECOVER-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[HANDLER_ALIGNMENT_ASSUMPTION:%.*]], !prof [[PROF3]], !nosanitize !2
-// CHECK-SANITIZE-NORECOVER:       handler.alignment_assumption:
-// CHECK-SANITIZE-NORECOVER-NEXT:    call void @__ubsan_handle_alignment_assumption_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP3]], i64 [[TMP1]], i64 0) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-NORECOVER-NEXT:    unreachable, !nosanitize !2
-// CHECK-SANITIZE-NORECOVER:       cont:
-// CHECK-SANITIZE-NORECOVER-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[TMP1]]) ]
-// CHECK-SANITIZE-NORECOVER-NEXT:    ret ptr [[CALL]]
-//
-// CHECK-SANITIZE-RECOVER-LABEL: define dso_local noundef ptr @_Z6callerPPcm
-// CHECK-SANITIZE-RECOVER-SAME: (ptr noundef [[X:%.*]], i64 noundef [[ALIGNMENT:%.*]]) #[[ATTR0]] {
-// CHECK-SANITIZE-RECOVER-NEXT:  entry:
-// CHECK-SANITIZE-RECOVER-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    [[ALIGNMENT_ADDR:%.*]] = alloca i64, align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    store i64 [[ALIGNMENT]], ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    [[TMP1:%.*]] = load i64, ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-RECOVER-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef [[TMP1]])
-// CHECK-SANITIZE-RECOVER-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-RECOVER-NEXT:    [[TMP2:%.*]] = sub i64 [[TMP1]], 1
-// CHECK-SANITIZE-RECOVER-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[TMP2]]
-// CHECK-SANITIZE-RECOVER-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-RECOVER-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-RECOVER-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[HANDLER_ALIGNMENT_ASSUMPTION:%.*]], !prof [[PROF3]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER:       handler.alignment_assumption:
-// CHECK-SANITIZE-RECOVER-NEXT:    call void @__ubsan_handle_alignment_assumption(ptr @[[GLOB3:[0-9]+]], i64 [[TMP3]], i64 [[TMP1]], i64 0) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER-NEXT:    br label [[CONT]], !nosanitize !2
-// CHECK-SANITIZE-RECOVER:       cont:
-// CHECK-SANITIZE-RECOVER-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[TMP1]]) ]
-// CHECK-SANITIZE-RECOVER-NEXT:    ret ptr [[CALL]]
-//
-// CHECK-SANITIZE-TRAP-LABEL: define dso_local noundef ptr @_Z6callerPPcm
-// CHECK-SANITIZE-TRAP-SAME: (ptr noundef [[X:%.*]], i64 noundef [[ALIGNMENT:%.*]]) #[[ATTR0]] {
-// CHECK-SANITIZE-TRAP-NEXT:  entry:
-// CHECK-SANITIZE-TRAP-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
-// CHECK-SANITIZE-TRAP-NEXT:    [[ALIGNMENT_ADDR:%.*]] = alloca i64, align 8
-// CHECK-SANITIZE-TRAP-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-TRAP-NEXT:    store i64 [[ALIGNMENT]], ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-TRAP-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
-// CHECK-SANITIZE-TRAP-NEXT:    [[TMP1:%.*]] = load i64, ptr [[ALIGNMENT_ADDR]], align 8
-// CHECK-SANITIZE-TRAP-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 noundef [[TMP1]])
-// CHECK-SANITIZE-TRAP-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[CALL]] to i64
-// CHECK-SANITIZE-TRAP-NEXT:    [[TMP2:%.*]] = sub i64 [[TMP1]], 1
-// CHECK-SANITIZE-TRAP-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[TMP2]]
-// CHECK-SANITIZE-TRAP-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-// CHECK-SANITIZE-TRAP-NEXT:    [[TMP3:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
-// CHECK-SANITIZE-TRAP-NEXT:    br i1 [[MASKCOND]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize !2
-// CHECK-SANITIZE-TRAP:       trap:
-// CHECK-SANITIZE-TRAP-NEXT:    call void @llvm.ubsantrap(i8 23) #[[ATTR3]], !nosanitize !2
-// CHECK-SANITIZE-TRAP-NEXT:    unreachable, !nosanitize !2
-// CHECK-SANITIZE-TRAP:       cont:
-// CHECK-SANITIZE-TRAP-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[TMP1]]) ]
-// CHECK-SANITIZE-TRAP-NEXT:    ret ptr [[CALL]]
+// CHECK-LABEL: define dso_local noundef ptr @_Z6callerPPcm
+// CHECK-SAME: (ptr noundef [[X:%.*]], i64 noundef [[ALIGNMENT:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    [[ALIGNMENT_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    store ptr [[X]], ptr [[X_ADDR]], align 8
+// CHECK-NEXT:    store i64 [[ALIGNMENT]], ptr [[ALIGNMENT_ADDR]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr [[ALIGNMENT_ADDR]], align 8
+// CHECK-NEXT:    [[CALL:%.*]] = call noundef ptr @_Z11passthroughPPcm(ptr noundef [[TMP0]], i64 allocalign noundef [[TMP1]])
+// CHECK-NEXT:    ret ptr [[CALL]]
 //
 char **caller(char **x, unsigned long alignment) {
 #line 100
   return passthrough(x, alignment);
 }
-//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-// CHECK: {{.*}}
Index: clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
===================================================================
--- clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
+++ clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
@@ -5,7 +5,7 @@
 
 // CHECK-LABEL: @t0_immediate0(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 16)
+// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 16)
 // CHECK-NEXT:    ret ptr [[CALL]]
 //
 void *t0_immediate0(void) {
@@ -14,7 +14,7 @@
 
 // CHECK-LABEL: @t1_immediate1(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 32)
+// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 32)
 // CHECK-NEXT:    ret ptr [[CALL]]
 //
 void *t1_immediate1(void) {
@@ -23,7 +23,7 @@
 
 // CHECK-LABEL: @t2_immediate2(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[CALL:%.*]] = call align 64 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 64)
+// CHECK-NEXT:    [[CALL:%.*]] = call align 64 ptr @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 64)
 // CHECK-NEXT:    ret ptr [[CALL]]
 //
 void *t2_immediate2(void) {
@@ -35,9 +35,7 @@
 // CHECK-NEXT:    [[ALIGNMENT_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store i32 [[ALIGNMENT:%.*]], ptr [[ALIGNMENT_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ALIGNMENT_ADDR]], align 4
-// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef [[TMP0]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call align 32 ptr @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef [[TMP0]])
 // CHECK-NEXT:    ret ptr [[CALL]]
 //
 void *t3_variable(int alignment) {
Index: clang/test/CodeGen/alloc-fns-alignment.c
===================================================================
--- clang/test/CodeGen/alloc-fns-alignment.c
+++ clang/test/CodeGen/alloc-fns-alignment.c
@@ -61,14 +61,12 @@
 // CHECK: declare ptr @realloc
 
 // CHECK-LABEL: @aligned_alloc_variable_test
-// CHECK:      %[[ALLOCATED:.*]] = call ptr @aligned_alloc({{i32|i64}} noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]])
-// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[ALLOCATED]], {{i32|i64}} %[[ALIGN]]) ]
+// CHECK:      %[[ALLOCATED:.*]] = call ptr @aligned_alloc({{i32|i64}} allocalign noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]])
 
 // CHECK: declare ptr @aligned_alloc
 
 // CHECK-LABEL: @memalign_variable_test
-// CHECK:      %[[ALLOCATED:.*]] = call ptr @memalign({{i32|i64}} noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]])
-// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[ALLOCATED]], {{i32|i64}} %[[ALIGN]]) ]
+// CHECK:      %[[ALLOCATED:.*]] = call ptr @memalign({{i32|i64}} allocalign noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]])
 
 // CHECK-LABEL: @aligned_alloc_constant_test
 // CHECK: call align 8 ptr @aligned_alloc
Index: clang/test/CodeGen/alloc-align-attr.c
===================================================================
--- clang/test/CodeGen/alloc-align-attr.c
+++ clang/test/CodeGen/alloc-align-attr.c
@@ -9,9 +9,7 @@
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m1(i32 noundef [[TMP0]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m1(i32 allocalign noundef [[TMP0]])
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -25,9 +23,7 @@
 // CHECK-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
 // CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[TMP0]] to i32
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m1(i32 noundef [[CONV]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = zext i32 [[CONV]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m1(i32 allocalign noundef [[CONV]])
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -43,8 +39,7 @@
 // CHECK-NEXT:    store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
 // CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m2(i64 noundef [[CONV]])
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CONV]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m2(i64 allocalign noundef [[CONV]])
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -58,8 +53,7 @@
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
 // CHECK-NEXT:    store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m2(i64 noundef [[TMP0]])
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[TMP0]]) ]
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m2(i64 allocalign noundef [[TMP0]])
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -79,23 +73,21 @@
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i128, align 16
 // CHECK-NEXT:    [[E:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
 // CHECK-NEXT:    [[COERCE:%.*]] = alloca i128, align 16
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 0
-// CHECK-NEXT:    store i64 [[A_COERCE0:%.*]], ptr [[TMP1]], align 16
-// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 1
-// CHECK-NEXT:    store i64 [[A_COERCE1:%.*]], ptr [[TMP2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    store i64 [[A_COERCE0:%.*]], ptr [[TMP0]], align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    store i64 [[A_COERCE1:%.*]], ptr [[TMP1]], align 8
 // CHECK-NEXT:    [[A1:%.*]] = load i128, ptr [[A]], align 16
 // CHECK-NEXT:    store i128 [[A1]], ptr [[A_ADDR]], align 16
-// CHECK-NEXT:    [[TMP3:%.*]] = load i128, ptr [[A_ADDR]], align 16
-// CHECK-NEXT:    store i128 [[TMP3]], ptr [[COERCE]], align 16
-// CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 0
-// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 16
-// CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 1
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP7]], align 8
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m3(i64 noundef [[TMP6]], i64 noundef [[TMP8]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = trunc i128 [[TMP3]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
-// CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[CALL]], align 4
-// CHECK-NEXT:    ret i32 [[TMP9]]
+// CHECK-NEXT:    [[TMP2:%.*]] = load i128, ptr [[A_ADDR]], align 16
+// CHECK-NEXT:    store i128 [[TMP2]], ptr [[COERCE]], align 16
+// CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 16
+// CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 1
+// CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 8
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m3(i64 noundef [[TMP4]], i64 allocalign noundef [[TMP6]])
+// CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[CALL]], align 4
+// CHECK-NEXT:    ret i32 [[TMP7]]
 //
 __INT32_TYPE__ test5(__int128_t a) {
   struct Empty e;
@@ -109,27 +101,25 @@
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i128, align 16
 // CHECK-NEXT:    [[E:%.*]] = alloca [[STRUCT_MULTIARGS:%.*]], align 8
 // CHECK-NEXT:    [[COERCE:%.*]] = alloca i128, align 16
-// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 0
-// CHECK-NEXT:    store i64 [[A_COERCE0:%.*]], ptr [[TMP1]], align 16
-// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 1
-// CHECK-NEXT:    store i64 [[A_COERCE1:%.*]], ptr [[TMP2]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    store i64 [[A_COERCE0:%.*]], ptr [[TMP0]], align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    store i64 [[A_COERCE1:%.*]], ptr [[TMP1]], align 8
 // CHECK-NEXT:    [[A1:%.*]] = load i128, ptr [[A]], align 16
 // CHECK-NEXT:    store i128 [[A1]], ptr [[A_ADDR]], align 16
-// CHECK-NEXT:    [[TMP3:%.*]] = load i128, ptr [[A_ADDR]], align 16
-// CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[E]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP2:%.*]] = load i128, ptr [[A_ADDR]], align 16
+// CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[E]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[E]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 8
-// CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[E]], i32 0, i32 1
-// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP7]], align 8
-// CHECK-NEXT:    store i128 [[TMP3]], ptr [[COERCE]], align 16
-// CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 0
-// CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 16
-// CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 1
-// CHECK-NEXT:    [[TMP13:%.*]] = load i64, ptr [[TMP12]], align 8
-// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m4(i64 [[TMP6]], i64 [[TMP8]], i64 noundef [[TMP11]], i64 noundef [[TMP13]])
-// CHECK-NEXT:    [[CASTED_ALIGN:%.*]] = trunc i128 [[TMP3]] to i64
-// CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[CASTED_ALIGN]]) ]
-// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[CALL]], align 4
-// CHECK-NEXT:    ret i32 [[TMP14]]
+// CHECK-NEXT:    store i128 [[TMP2]], ptr [[COERCE]], align 16
+// CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP7]], align 16
+// CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds { i64, i64 }, ptr [[COERCE]], i32 0, i32 1
+// CHECK-NEXT:    [[TMP10:%.*]] = load i64, ptr [[TMP9]], align 8
+// CHECK-NEXT:    [[CALL:%.*]] = call ptr @m4(i64 [[TMP4]], i64 allocalign [[TMP6]], i64 noundef [[TMP8]], i64 noundef [[TMP10]])
+// CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[CALL]], align 4
+// CHECK-NEXT:    ret i32 [[TMP11]]
 //
 __INT32_TYPE__ test6(__int128_t a) {
   struct MultiArgs e;
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -4829,17 +4829,6 @@
     AA = nullptr; // We're done. Disallow doing anything else.
     return NewAttrs;
   }
-
-  /// Emit alignment assumption.
-  /// This is a general fallback that we take if either there is an offset,
-  /// or the alignment is variable or we are sanitizing for alignment.
-  void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
-    if (!AA)
-      return;
-    CGF.emitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc,
-                                AA->getLocation(), Alignment, OffsetCI);
-    AA = nullptr; // We're done. Disallow doing anything else.
-  }
 };
 
 /// Helper data structure to emit `AssumeAlignedAttr`.
@@ -4858,6 +4847,17 @@
         OffsetCI = nullptr;
     }
   }
+
+  /// Emit alignment assumption.
+  /// This is a general fallback that we take if either there is an offset,
+  /// or the alignment is variable or we are sanitizing for alignment.
+  void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
+    if (!AA)
+      return;
+    CGF.emitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc,
+                                AA->getLocation(), Alignment, OffsetCI);
+    AA = nullptr; // We're done. Disallow doing anything else.
+  }
 };
 
 /// Helper data structure to emit `AllocAlignAttr`.
@@ -4874,6 +4874,24 @@
                     .getRValue(CGF)
                     .getScalarVal();
   }
+
+  [[nodiscard]] llvm::AttributeList
+  TryEmitAsCallSiteAttribute(const llvm::AttributeList &Attrs) {
+    llvm::AttributeList NewAttrs = Attrs;
+    if (AA)
+      NewAttrs = NewAttrs.addParamAttribute(CGF.getLLVMContext(),
+                                            AA->getParamIndex().getLLVMIndex(),
+                                            llvm::Attribute::AllocAlign);
+    // NOTE: we shouldn't _need_ to emit this `align` attribute here, but there
+    // are some interesting cases where LLVM can manage to delete the arguments
+    // to a function that has the `alloc_align` attribute on it, and then the
+    // alignment gets lost. An example of this is the failure you'll get in
+    // clang/test/Headers/mm_malloc.c if this `align` is omitted, because
+    // _mm_malloc ends up getting its arguments turned into constants that get
+    // passed to posix_memalign, which we don't have logic to handle in LLVM.
+    return AbstractAssumeAlignedAttrEmitter<
+        AllocAlignAttr>::TryEmitAsCallSiteAttribute(NewAttrs);
+  }
 };
 
 } // namespace
@@ -5807,7 +5825,6 @@
   // Emit the assume_aligned check on the return value.
   if (Ret.isScalar() && TargetDecl) {
     AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
-    AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
   }
 
   // Explicitly call CallLifetimeEnd::Emit just to re-use the code even though
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to