diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4635,17 +4635,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`. @@ -4664,6 +4653,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`. @@ -4680,6 +4680,24 @@ .getRValue(CGF) .getScalarVal(); } + + LLVM_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 @@ -5572,7 +5590,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 diff --git a/clang/test/CodeGen/alloc-align-attr.c b/clang/test/CodeGen/alloc-align-attr.c --- a/clang/test/CodeGen/alloc-align-attr.c +++ b/clang/test/CodeGen/alloc-align-attr.c @@ -9,9 +9,7 @@ // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 noundef [[TMP0]]) -// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64 -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 allocalign noundef [[TMP0]]) // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 // CHECK-NEXT: ret i32 [[TMP1]] // @@ -25,9 +23,7 @@ // CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8 // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 noundef [[CONV]]) -// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = zext i32 [[CONV]] to i64 -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 allocalign noundef [[CONV]]) // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 // CHECK-NEXT: ret i32 [[TMP1]] // @@ -43,8 +39,7 @@ // CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 // CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 noundef [[CONV]]) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[CONV]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 allocalign noundef [[CONV]]) // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[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:%.*]], i64* [[A_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 noundef [[TMP0]]) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[CALL]], i64 [[TMP0]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 allocalign noundef [[TMP0]]) // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 // CHECK-NEXT: ret i32 [[TMP1]] // @@ -93,9 +87,7 @@ // CHECK-NEXT: [[TMP6:%.*]] = load i64, i64* [[TMP5]], align 16 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 1 // CHECK-NEXT: [[TMP8:%.*]] = load i64, i64* [[TMP7]], align 8 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @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"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m3(i64 noundef [[TMP6]], i64 allocalign noundef [[TMP8]]) // CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[CALL]], align 4 // CHECK-NEXT: ret i32 [[TMP9]] // @@ -130,9 +122,7 @@ // CHECK-NEXT: [[TMP11:%.*]] = load i64, i64* [[TMP10]], align 16 // CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP9]], i32 0, i32 1 // CHECK-NEXT: [[TMP13:%.*]] = load i64, i64* [[TMP12]], align 8 -// CHECK-NEXT: [[CALL:%.*]] = call i32* @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"(i32* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m4(i64 [[TMP6]], i64 allocalign [[TMP8]], i64 noundef [[TMP11]], i64 noundef [[TMP13]]) // CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[CALL]], align 4 // CHECK-NEXT: ret i32 [[TMP14]] // diff --git a/clang/test/CodeGen/alloc-fns-alignment.c b/clang/test/CodeGen/alloc-fns-alignment.c --- a/clang/test/CodeGen/alloc-fns-alignment.c +++ b/clang/test/CodeGen/alloc-fns-alignment.c @@ -61,14 +61,12 @@ // CHECK: declare i8* @realloc // CHECK-LABEL: @aligned_alloc_variable_test -// CHECK: %[[ALLOCATED:.*]] = call i8* @aligned_alloc({{i32|i64}} noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]]) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[ALLOCATED]], {{i32|i64}} %[[ALIGN]]) ] +// CHECK: %[[ALLOCATED:.*]] = call i8* @aligned_alloc({{i32|i64}} allocalign noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]]) // CHECK: declare i8* @aligned_alloc // CHECK-LABEL: @memalign_variable_test -// CHECK: %[[ALLOCATED:.*]] = call i8* @memalign({{i32|i64}} noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]]) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[ALLOCATED]], {{i32|i64}} %[[ALIGN]]) ] +// CHECK: %[[ALLOCATED:.*]] = call i8* @memalign({{i32|i64}} allocalign noundef %[[ALIGN:.*]], {{i32|i64}} noundef %[[NBYTES:.*]]) // CHECK-LABEL: @aligned_alloc_constant_test // CHECK: call align 8 i8* @aligned_alloc diff --git a/clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c b/clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c --- a/clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c +++ b/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 i8* @my_aligned_alloc(i32 noundef 320, i32 noundef 16) +// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 16) // CHECK-NEXT: ret i8* [[CALL]] // void *t0_immediate0(void) { @@ -14,7 +14,7 @@ // CHECK-LABEL: @t1_immediate1( // CHECK-NEXT: entry: -// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @my_aligned_alloc(i32 noundef 320, i32 noundef 32) +// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 32) // CHECK-NEXT: ret i8* [[CALL]] // void *t1_immediate1(void) { @@ -23,7 +23,7 @@ // CHECK-LABEL: @t2_immediate2( // CHECK-NEXT: entry: -// CHECK-NEXT: [[CALL:%.*]] = call align 64 i8* @my_aligned_alloc(i32 noundef 320, i32 noundef 64) +// CHECK-NEXT: [[CALL:%.*]] = call align 64 i8* @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef 64) // CHECK-NEXT: ret i8* [[CALL]] // void *t2_immediate2(void) { @@ -35,9 +35,7 @@ // CHECK-NEXT: [[ALIGNMENT_ADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[ALIGNMENT:%.*]], i32* [[ALIGNMENT_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ALIGNMENT_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @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"(i8* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call align 32 i8* @my_aligned_alloc(i32 noundef 320, i32 allocalign noundef [[TMP0]]) // CHECK-NEXT: ret i8* [[CALL]] // void *t3_variable(int alignment) { diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp --- a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp @@ -1,11 +1,12 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -// RUN: %clang_cc1 -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE +// RUN: %clang_cc1 -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER -// RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE +// RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP // CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char **'\00" } -// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] } +// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 23 }, {{.*}}* @[[CHAR]] } +#line 100 char **__attribute__((alloc_align(2))) passthrough(char **x, unsigned long alignment) { // CHECK: define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]]) @@ -51,22 +52,8 @@ // CHECK-NEXT: store i64 %[[ALIGNMENT]], i64* %[[ALIGNMENT_ADDR]], align 8 // CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8 // CHECK-NEXT: %[[ALIGNMENT_RELOADED:.*]] = load i64, i64* %[[ALIGNMENT_ADDR]], align 8 - // CHECK-NEXT: %[[X_RETURNED:.*]] = call noundef i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 noundef %[[ALIGNMENT_RELOADED]]) - // CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64 - // CHECK-SANITIZE-NEXT: %[[MASK:.*]] = sub i64 %[[ALIGNMENT_RELOADED]], 1 - // CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], %[[MASK]] - // CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0 - // CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize - // CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize - // CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 %[[ALIGNMENT_RELOADED]], i64 0){{.*}}, !nosanitize - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 %[[ALIGNMENT_RELOADED]], i64 0){{.*}}, !nosanitize - // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize - // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize - // CHECK-SANITIZE: [[CONT]]: - // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** %[[X_RETURNED]], i64 %1) ] + // CHECK-NEXT: %[[X_RETURNED:.*]] = call noundef i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 allocalign noundef %[[ALIGNMENT_RELOADED]]) // CHECK-NEXT: ret i8** %[[X_RETURNED]] // CHECK-NEXT: } -#line 100 return passthrough(x, alignment); } diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp --- a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp @@ -1,11 +1,12 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE -// RUN: %clang_cc1 -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE +// RUN: %clang_cc1 -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER -// RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE +// RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP // CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char **'\00" } -// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] } +// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 23 }, {{.*}}* @[[CHAR]] } +#line 100 char **__attribute__((alloc_align(2))) passthrough(char **x, unsigned long alignment) { // CHECK: define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]]) @@ -49,22 +50,9 @@ // CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8 // CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8 // CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8 - // CHECK-NOSANITIZE-NEXT: %[[X_RETURNED:.*]] = call noundef align 128 i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 noundef 128) - // CHECK-SANITIZE-NEXT: %[[X_RETURNED:.*]] = call noundef i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 noundef 128) - // CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64 - // CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 127 - // CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0 - // CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize - // CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize - // CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 128, i64 0){{.*}}, !nosanitize - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 128, i64 0){{.*}}, !nosanitize - // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize - // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize - // CHECK-SANITIZE: [[CONT]]: - // CHECK-SANITIZE-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** %[[X_RETURNED]], i64 128) ] - // CHECK-NEXT: ret i8** %[[X_RETURNED]] + // CHECK-NOSANITIZE-NEXT: %call = call noundef align 128 i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 allocalign noundef 128) + // CHECK-SANITIZE-NEXT: %call = call noundef i8** @[[PASSTHROUGH]](i8** noundef %[[X_RELOADED]], i64 allocalign noundef 128) + // CHECK-NEXT: ret i8** %call // CHECK-NEXT: } -#line 100 return passthrough(x, 128); } diff --git a/clang/test/CodeGen/non-power-of-2-alignment-assumptions.c b/clang/test/CodeGen/non-power-of-2-alignment-assumptions.c --- a/clang/test/CodeGen/non-power-of-2-alignment-assumptions.c +++ b/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:%.*]], i32* [[ALIGN_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ALIGN_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call i8* @alloc(i32 noundef [[TMP0]]) -// CHECK-NEXT: [[CASTED_ALIGN:%.*]] = zext i32 [[TMP0]] to i64 -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[CALL]], i64 [[CASTED_ALIGN]]) ] +// CHECK-NEXT: [[CALL:%.*]] = call i8* @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:%.*]], i32* [[ALIGN_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call i8* @alloc(i32 noundef 7) -// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[CALL]], i64 7) ] +// CHECK-NEXT: [[CALL:%.*]] = call i8* @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:%.*]], i32* [[ALIGN_ADDR]], align 4 -// CHECK-NEXT: [[CALL:%.*]] = call align 8 i8* @alloc(i32 noundef 8) +// CHECK-NEXT: [[CALL:%.*]] = call align 8 i8* @alloc(i32 allocalign noundef 8) // CHECK-NEXT: ret void // void t2(int align) { diff --git a/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp b/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp --- a/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp +++ b/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 i8* @_ZnwmSt11align_val_t(i64 noundef 4, i64 noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] + // CHECK: call noalias noundef nonnull align 4 i8* @_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)); } diff --git a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp --- a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp +++ b/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 i8* @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 32) +// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @_ZnwmSt11align_val_t(i64 noundef 512, i64 allocalign noundef 32) // CHECK: call void @_ZdlPvSt11align_val_t(i8* noundef %[[ALLOC]], i64 noundef 32) // CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"() -// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef 512, i64 noundef 32) +// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @"??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"(i8* 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 i8* @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 noundef 32) +// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @_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(i8* noundef %[[ALLOC]], i64 noundef 32) // CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"( -// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef %{{.*}}, i64 noundef 32) +// CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef %{{.*}}, i64 allocalign noundef 32) // No array cookie. // CHECK-MS-NOT: store // CHECK-MS: invoke noundef %struct.A* @"??0A@@QEAA@XZ"( @@ -84,7 +84,7 @@ void *b0() { return new B; } // CHECK-LABEL: define {{.*}} @_Z2b1l( -// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @_ZnamSt11align_val_t(i64 noundef %{{.*}}, i64 noundef 32) +// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 i8* @_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 i8* @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 4) +// CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 4 i8* @_ZnwmSt11align_val_t(i64 noundef 512, i64 allocalign noundef 4) // CHECK: call void @_ZdlPvSt11align_val_t(i8* noundef %[[ALLOC]], i64 noundef 4) void *e0() { return new (std::align_val_t(4)) A; }