[IR] Make dead_on_return attribute optionally sized

This patch makes the dead_on_return parameter attribute optionally require a number
of bytes to be passed in to specify the number of bytes known to be dead
upon function return/unwind. This is aimed at enabling annotating the
this pointer in C++ destructors with dead_on_return in clang. We need
this to handle cases like the following:

```
struct X {
  int n;
  ~X() {
    this[n].n = 0;
  }
};
void f() {
  X xs[] = {42, -1};
}
```

Where we only certain that sizeof(X) bytes are dead upon return of ~X.
Otherwise DSE would be able to eliminate the store in ~X which would not
be correct.

This patch only does the wiring within IR. Future patches will make
clang emit correct sizing information and update DSE to only delete
stores to objects marked dead_on_return that are provably in bounds of
the number of bytes specified to be dead_on_return.

Reviewers: nikic, alinas, antoniofrighetto

Pull Request: https://github.com/llvm/llvm-project/pull/171712
This commit is contained in:
Aiden Grossman 2026-01-21 08:22:05 -08:00 committed by GitHub
parent 224f2bdc37
commit e2d7cd685d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
105 changed files with 2014 additions and 1874 deletions

View file

@ -2884,7 +2884,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// (e.g., Obj-C ARC-managed structs, MSVC callee-destroyed objects).
if (!ParamType.isDestructedType() || !ParamType->isRecordType() ||
ParamType->castAsRecordDecl()->isParamDestroyedInCallee())
Attrs.addAttribute(llvm::Attribute::DeadOnReturn);
Attrs.addDeadOnReturnAttr(llvm::DeadOnReturnInfo());
}
}

View file

@ -34,7 +34,7 @@ EXTERNC int empty_align16_arg(struct EmptyAlign16 a, int b) {
return b;
}
// CXX: define{{.*}} i32 @empty_align32_arg(ptr dead_on_return noundef %a, i32 noundef %b)
// CXX: define{{.*}} i32 @empty_align32_arg(ptr noundef dead_on_return %a, i32 noundef %b)
struct EmptyAlign32 { long long int __attribute__((aligned(32))) : 0; };
EXTERNC int empty_align32_arg(struct EmptyAlign32 a, int b) {
return b;

View file

@ -30,10 +30,10 @@ void example(void) {
// Then, memcpy `l` to the temporary stack space.
// CHECK-O0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[byvaltemp]], ptr align 8 %[[l]], i64 64, i1 false)
// Finally, call using a pointer to the temporary stack space.
// CHECK-O0-NEXT: call void @pass_large(ptr dead_on_return noundef %[[byvaltemp]])
// CHECK-O0-NEXT: call void @pass_large(ptr noundef dead_on_return %[[byvaltemp]])
// Now, do the same for the second call, using the second temporary alloca.
// CHECK-O0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[byvaltemp1]], ptr align 8 %[[l]], i64 64, i1 false)
// CHECK-O0-NEXT: call void @pass_large(ptr dead_on_return noundef %[[byvaltemp1]])
// CHECK-O0-NEXT: call void @pass_large(ptr noundef dead_on_return %[[byvaltemp1]])
// CHECK-O0-NEXT: ret void
//
// At O3, we should have lifetime markers to help the optimizer re-use the temporary allocas.
@ -58,7 +58,7 @@ void example(void) {
// Then, memcpy `l` to the temporary stack space.
// CHECK-O3-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[byvaltemp]], ptr align 8 %[[l]], i64 64, i1 false)
// Finally, call using a pointer to the temporary stack space.
// CHECK-O3-NEXT: call void @pass_large(ptr dead_on_return noundef %[[byvaltemp]])
// CHECK-O3-NEXT: call void @pass_large(ptr noundef dead_on_return %[[byvaltemp]])
//
// The lifetime of the temporary used to pass a pointer to the struct ends here.
// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(ptr %[[byvaltemp]])
@ -66,7 +66,7 @@ void example(void) {
// Now, do the same for the second call, using the second temporary alloca.
// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(ptr %[[byvaltemp1]])
// CHECK-O3-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[byvaltemp1]], ptr align 8 %[[l]], i64 64, i1 false)
// CHECK-O3-NEXT: call void @pass_large(ptr dead_on_return noundef %[[byvaltemp1]])
// CHECK-O3-NEXT: call void @pass_large(ptr noundef dead_on_return %[[byvaltemp1]])
// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(ptr %[[byvaltemp1]])
//
// Mark the end of the lifetime of `l`.
@ -88,12 +88,12 @@ void example_BitInt(void) {
// CHECK-O0-NEXT: [[LOADEDV:%.*]] = trunc i256 [[TMP0]] to i129
// CHECK-O0-NEXT: [[STOREDV:%.*]] = sext i129 [[LOADEDV]] to i256
// CHECK-O0-NEXT: store i256 [[STOREDV]], ptr [[INDIRECT_ARG_TEMP]], align 16
// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr dead_on_return noundef [[INDIRECT_ARG_TEMP]])
// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr noundef dead_on_return [[INDIRECT_ARG_TEMP]])
// CHECK-O0-NEXT: [[TMP1:%.*]] = load i256, ptr [[L]], align 16
// CHECK-O0-NEXT: [[LOADEDV1:%.*]] = trunc i256 [[TMP1]] to i129
// CHECK-O0-NEXT: [[STOREDV1:%.*]] = sext i129 [[LOADEDV1]] to i256
// CHECK-O0-NEXT: store i256 [[STOREDV1]], ptr [[INDIRECT_ARG_TEMP1]], align 16
// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr dead_on_return noundef [[INDIRECT_ARG_TEMP1]])
// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr noundef dead_on_return [[INDIRECT_ARG_TEMP1]])
// CHECK-O0-NEXT: ret void
//
// CHECK-O3-LABEL: define dso_local void @example_BitInt(
@ -108,13 +108,13 @@ void example_BitInt(void) {
// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(ptr [[INDIRECT_ARG_TEMP]])
// CHECK-O3-NEXT: [[STOREDV:%.*]] = sext i129 [[LOADEDV]] to i256
// CHECK-O3-NEXT: store i256 [[STOREDV]], ptr [[INDIRECT_ARG_TEMP]], align 16, !tbaa [[TBAA6]]
// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr dead_on_return noundef [[INDIRECT_ARG_TEMP]])
// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr noundef dead_on_return [[INDIRECT_ARG_TEMP]])
// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(ptr [[INDIRECT_ARG_TEMP]])
// CHECK-O3-NEXT: [[TMP1:%.*]] = load i256, ptr [[L]], align 16, !tbaa [[TBAA6]]
// CHECK-O3-NEXT: [[LOADEDV1:%.*]] = trunc i256 [[TMP1]] to i129
// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(ptr [[INDIRECT_ARG_TEMP1]])
// CHECK-O3-NEXT: [[STOREDV1:%.*]] = sext i129 [[LOADEDV1]] to i256
// CHECK-O3-NEXT: store i256 [[STOREDV1]], ptr [[INDIRECT_ARG_TEMP1]], align 16, !tbaa [[TBAA6]]
// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr dead_on_return noundef [[INDIRECT_ARG_TEMP1]])
// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr noundef dead_on_return [[INDIRECT_ARG_TEMP1]])
// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(ptr [[INDIRECT_ARG_TEMP1]])
// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(ptr [[L]])

View file

@ -19,7 +19,7 @@ void f0(S0 *p) {
use0(*p);
}
// CHECK-C: declare void @use0(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>)
// CHECK-CXX: declare void @use0(ptr dead_on_return noundef)
// CHECK-CXX: declare void @use0(ptr noundef dead_on_return)
#ifdef __cplusplus

View file

@ -92,7 +92,7 @@ void test_argpass_simple(PST *p) {
// CHECK-AAPCS-NEXT: ret void
// CHECK-AAPCS: declare void @argpass_simple_callee(<vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_simple_callee(ptr dead_on_return noundef)
// CHECK-DARWIN: declare void @argpass_simple_callee(ptr noundef dead_on_return)
// Boundary case of using the last available Z-reg, PST expanded.
// 0.0 -> d0-d3
@ -107,7 +107,7 @@ void test_argpass_last_z(PST *p) {
argpass_last_z_callee(.0, .0, .0, .0, *p);
}
// CHECK-AAPCS: declare void @argpass_last_z_callee(double noundef, double noundef, double noundef, double noundef, <vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_last_z_callee(double noundef, double noundef, double noundef, double noundef, ptr dead_on_return noundef)
// CHECK-DARWIN: declare void @argpass_last_z_callee(double noundef, double noundef, double noundef, double noundef, ptr noundef dead_on_return)
// Like the above, but using a tuple type to occupy some registers.
@ -123,7 +123,7 @@ void test_argpass_last_z_tuple(PST *p, svfloat64x4_t x) {
argpass_last_z_tuple_callee(x, *p);
}
// CHECK-AAPCS: declare void @argpass_last_z_tuple_callee(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_last_z_tuple_callee(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, ptr dead_on_return noundef)
// CHECK-DARWIN: declare void @argpass_last_z_tuple_callee(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, ptr noundef dead_on_return)
// Boundary case of using the last available P-reg, PST expanded.
@ -139,7 +139,7 @@ void test_argpass_last_p(PST *p) {
argpass_last_p_callee(svpfalse(), svpfalse_c(), *p);
}
// CHECK-AAPCS: declare void @argpass_last_p_callee(<vscale x 16 x i1>, target("aarch64.svcount"), <vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_last_p_callee(<vscale x 16 x i1>, target("aarch64.svcount"), ptr dead_on_return noundef)
// CHECK-DARWIN: declare void @argpass_last_p_callee(<vscale x 16 x i1>, target("aarch64.svcount"), ptr noundef dead_on_return)
// Not enough Z-regs, push PST to memory and pass a pointer, Z-regs and
@ -157,7 +157,7 @@ void test_argpass_no_z(PST *p, double dummy, svmfloat8_t u, int8x16_t v, mfloat8
void argpass_no_z_callee(svmfloat8_t, int8x16_t, mfloat8x16_t, double, double, int, PST, int, double, svbool_t);
argpass_no_z_callee(u, v, w, .0, .0, 1, *p, 2, 3.0, svptrue_b64());
}
// CHECK: declare void @argpass_no_z_callee(<vscale x 16 x i8>, <16 x i8> noundef, <16 x i8>, double noundef, double noundef, i32 noundef, ptr dead_on_return noundef, i32 noundef, double noundef, <vscale x 16 x i1>)
// CHECK: declare void @argpass_no_z_callee(<vscale x 16 x i8>, <16 x i8> noundef, <16 x i8>, double noundef, double noundef, i32 noundef, ptr noundef dead_on_return, i32 noundef, double noundef, <vscale x 16 x i1>)
// Like the above, using a tuple to occupy some registers.
@ -173,7 +173,7 @@ void test_argpass_no_z_tuple_f64(PST *p, float dummy, svfloat64x4_t x) {
double, svbool_t);
argpass_no_z_tuple_f64_callee(x, .0, 1, *p, 2, 3.0, svptrue_b64());
}
// CHECK: declare void @argpass_no_z_tuple_f64_callee(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, double noundef, i32 noundef, ptr dead_on_return noundef, i32 noundef, double noundef, <vscale x 16 x i1>)
// CHECK: declare void @argpass_no_z_tuple_f64_callee(<vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, double noundef, i32 noundef, ptr noundef dead_on_return, i32 noundef, double noundef, <vscale x 16 x i1>)
// Likewise, using a different tuple.
@ -189,7 +189,7 @@ void test_argpass_no_z_tuple_mfp8(PST *p, float dummy, svmfloat8x4_t x) {
double, svbool_t);
argpass_no_z_tuple_mfp8_callee(x, .0, 1, *p, 2, 3.0, svptrue_b64());
}
// CHECK: declare void @argpass_no_z_tuple_mfp8_callee(<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, double noundef, i32 noundef, ptr dead_on_return noundef, i32 noundef, double noundef, <vscale x 16 x i1>)
// CHECK: declare void @argpass_no_z_tuple_mfp8_callee(<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, double noundef, i32 noundef, ptr noundef dead_on_return, i32 noundef, double noundef, <vscale x 16 x i1>)
// Not enough Z-regs (consumed by a HFA), PST passed indirectly
@ -204,8 +204,8 @@ void test_argpass_no_z_hfa(HFA *h, PST *p) {
void argpass_no_z_hfa_callee(double, HFA, int, PST, int, svbool_t);
argpass_no_z_hfa_callee(.0, *h, 1, *p, 2, svptrue_b64());
}
// CHECK-AAPCS: declare void @argpass_no_z_hfa_callee(double noundef, [4 x float] alignstack(8), i32 noundef, ptr dead_on_return noundef, i32 noundef, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_no_z_hfa_callee(double noundef, [4 x float], i32 noundef, ptr dead_on_return noundef, i32 noundef, <vscale x 16 x i1>)
// CHECK-AAPCS: declare void @argpass_no_z_hfa_callee(double noundef, [4 x float] alignstack(8), i32 noundef, ptr noundef dead_on_return, i32 noundef, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_no_z_hfa_callee(double noundef, [4 x float], i32 noundef, ptr noundef dead_on_return, i32 noundef, <vscale x 16 x i1>)
// Not enough Z-regs (consumed by a HVA), PST passed indirectly
// 0.0 -> d0
@ -219,8 +219,8 @@ void test_argpass_no_z_hva(HVA *h, PST *p) {
void argpass_no_z_hva_callee(double, HVA, int, PST, int, svbool_t);
argpass_no_z_hva_callee(.0, *h, 1, *p, 2, svptrue_b64());
}
// CHECK-AAPCS: declare void @argpass_no_z_hva_callee(double noundef, [4 x <16 x i8>] alignstack(16), i32 noundef, ptr dead_on_return noundef, i32 noundef, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_no_z_hva_callee(double noundef, [4 x <16 x i8>], i32 noundef, ptr dead_on_return noundef, i32 noundef, <vscale x 16 x i1>)
// CHECK-AAPCS: declare void @argpass_no_z_hva_callee(double noundef, [4 x <16 x i8>] alignstack(16), i32 noundef, ptr noundef dead_on_return, i32 noundef, <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @argpass_no_z_hva_callee(double noundef, [4 x <16 x i8>], i32 noundef, ptr noundef dead_on_return, i32 noundef, <vscale x 16 x i1>)
// Not enough P-regs, PST passed indirectly, Z-regs and P-regs still available.
// true -> p0-p2
@ -233,7 +233,7 @@ void test_argpass_no_p(PST *p) {
void argpass_no_p_callee(svbool_t, svbool_t, svbool_t, int, PST, int, double, svbool_t);
argpass_no_p_callee(svptrue_b8(), svptrue_b16(), svptrue_b32(), 1, *p, 2, 3.0, svptrue_b64());
}
// CHECK: declare void @argpass_no_p_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, i32 noundef, ptr dead_on_return noundef, i32 noundef, double noundef, <vscale x 16 x i1>)
// CHECK: declare void @argpass_no_p_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, i32 noundef, ptr noundef dead_on_return, i32 noundef, double noundef, <vscale x 16 x i1>)
// Like above, using a tuple to occupy some registers.
@ -250,7 +250,7 @@ void test_argpass_no_p_tuple(PST *p, svbool_t u, svboolx2_t v) {
svbool_t);
argpass_no_p_tuple_callee(v, u, 1, *p, 2, 3.0, svptrue_b64());
}
// CHECK: declare void @argpass_no_p_tuple_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, i32 noundef, ptr dead_on_return noundef, i32 noundef, double noundef, <vscale x 16 x i1>)
// CHECK: declare void @argpass_no_p_tuple_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, i32 noundef, ptr noundef dead_on_return, i32 noundef, double noundef, <vscale x 16 x i1>)
// HFAs go back-to-back to memory, afterwards Z-regs not available, PST passed indirectly.
@ -263,8 +263,8 @@ void test_after_hfa(HFA *h, PST *p) {
void after_hfa_callee(double, double, double, double, double, HFA, PST, HFA, svbool_t);
after_hfa_callee(.0, .0, .0, .0, .0, *h, *p, *h, svpfalse());
}
// CHECK-AAPCS: declare void @after_hfa_callee(double noundef, double noundef, double noundef, double noundef, double noundef, [4 x float] alignstack(8), ptr dead_on_return noundef, [4 x float] alignstack(8), <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @after_hfa_callee(double noundef, double noundef, double noundef, double noundef, double noundef, [4 x float], ptr dead_on_return noundef, [4 x float], <vscale x 16 x i1>)
// CHECK-AAPCS: declare void @after_hfa_callee(double noundef, double noundef, double noundef, double noundef, double noundef, [4 x float] alignstack(8), ptr noundef dead_on_return, [4 x float] alignstack(8), <vscale x 16 x i1>)
// CHECK-DARWIN: declare void @after_hfa_callee(double noundef, double noundef, double noundef, double noundef, double noundef, [4 x float], ptr noundef dead_on_return, [4 x float], <vscale x 16 x i1>)
// Small PST, not enough registers, passed indirectly, unlike other small
// aggregates.
@ -277,7 +277,7 @@ void test_small_pst(SmallPST *p, SmallAgg *s) {
void small_pst_callee(SmallAgg, double, double, double, double, double, double, double, double, double, SmallPST, double);
small_pst_callee(*s, .0, .0, .0, .0, .0, .0, .0, .0, 1.0, *p, 2.0);
}
// CHECK-AAPCS: declare void @small_pst_callee([2 x i64], double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, ptr dead_on_return noundef, double noundef)
// CHECK-AAPCS: declare void @small_pst_callee([2 x i64], double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, ptr noundef dead_on_return, double noundef)
// CHECK-DARWIN: declare void @small_pst_callee([2 x i64], double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, double noundef, i128, double noundef)
@ -326,12 +326,12 @@ void test_pass_variadic(PST *p, PST *q) {
pass_variadic_callee(*p, *q);
}
// CHECK-AAPCS: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(96) %byval-temp, ptr noundef nonnull align 16 dereferenceable(96) %q, i64 96, i1 false)
// CHECK-AAPCS: call void (<vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>, ...) @pass_variadic_callee(<vscale x 16 x i1> %1, <vscale x 2 x double> %cast.scalable1, <vscale x 4 x float> %cast.scalable2, <vscale x 4 x float> %cast.scalable3, <vscale x 16 x i8> %cast.scalable4, <vscale x 16 x i1> %12, ptr dead_on_return noundef nonnull %byval-temp)
// CHECK-AAPCS: call void (<vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>, ...) @pass_variadic_callee(<vscale x 16 x i1> %1, <vscale x 2 x double> %cast.scalable1, <vscale x 4 x float> %cast.scalable2, <vscale x 4 x float> %cast.scalable3, <vscale x 16 x i8> %cast.scalable4, <vscale x 16 x i1> %12, ptr noundef nonnull dead_on_return %byval-temp)
// CHECK-DARWIN: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(96) %byval-temp, ptr noundef nonnull align 16 dereferenceable(96) %p, i64 96, i1 false)
// CHECK-DARWIN: call void @llvm.lifetime.start.p0(ptr nonnull %byval-temp1)
// CHECK-DARWIN: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(96) %byval-temp1, ptr noundef nonnull align 16 dereferenceable(96) %q, i64 96, i1 false)
// CHECK-DARWIN: call void (ptr, ...) @pass_variadic_callee(ptr dead_on_return noundef nonnull %byval-temp, ptr dead_on_return noundef nonnull %byval-temp1)
// CHECK-DARWIN: call void (ptr, ...) @pass_variadic_callee(ptr noundef nonnull dead_on_return %byval-temp, ptr noundef nonnull dead_on_return %byval-temp1)
// Test passing a small PST, still passed indirectly, despite being <= 128 bits
@ -340,7 +340,7 @@ void test_small_pst_variadic(SmallPST *p) {
small_pst_variadic_callee(0, *p);
}
// CHECK-AAPCS: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) %byval-temp, ptr noundef nonnull align 16 dereferenceable(16) %p, i64 16, i1 false)
// CHECK-AAPCS: call void (i32, ...) @small_pst_variadic_callee(i32 noundef 0, ptr dead_on_return noundef nonnull %byval-temp)
// CHECK-AAPCS: call void (i32, ...) @small_pst_variadic_callee(i32 noundef 0, ptr noundef nonnull dead_on_return %byval-temp)
// CHECK-DARWIN: %0 = load i128, ptr %p, align 16
// CHECK-DARWIN: tail call void (i32, ...) @small_pst_variadic_callee(i32 noundef 0, i128 %0)
@ -467,7 +467,7 @@ void test_tuple_reg_count(svfloat32_t x, svfloat32x2_t y) {
svfloat32_t, svfloat32_t, svfloat32_t, svfloat32x2_t);
test_tuple_reg_count_callee(x, x, x, x, x, x, x, y);
}
// CHECK-AAPCS: declare void @test_tuple_reg_count_callee(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, ptr dead_on_return noundef)
// CHECK-AAPCS: declare void @test_tuple_reg_count_callee(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, ptr noundef dead_on_return)
// CHECK-DARWIN: declare void @test_tuple_reg_count_callee(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>)
// Regression test for incorrect passing of SVE vector tuples
@ -476,5 +476,5 @@ void test_tuple_reg_count_bool(svboolx4_t x, svboolx4_t y) {
void test_tuple_reg_count_bool_callee(svboolx4_t, svboolx4_t);
test_tuple_reg_count_bool_callee(x, y);
}
// CHECK-AAPCS: declare void @test_tuple_reg_count_bool_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, ptr dead_on_return noundef)
// CHECK-AAPCS: declare void @test_tuple_reg_count_bool_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, ptr noundef dead_on_return)
// CHECK-DARWIN: declare void @test_tuple_reg_count_bool_callee(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>)

View file

@ -82,7 +82,7 @@ struct Sppp {
int *x, *y, *z;
};
// CHECK-A64-LABEL: define dso_local void @_Z4Tppp4Sppp(
// CHECK-A64-SAME: ptr dead_on_return noundef [[S:%.*]]) #[[ATTR0]] {
// CHECK-A64-SAME: ptr noundef dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-A64-NEXT: [[ENTRY:.*:]]
// CHECK-A64-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
// CHECK-A64-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
@ -490,7 +490,7 @@ struct Spa3 {
int* xs[3];
};
// CHECK-A64-LABEL: define dso_local void @_Z4Tpa34Spa3(
// CHECK-A64-SAME: ptr dead_on_return noundef [[S:%.*]]) #[[ATTR0]] {
// CHECK-A64-SAME: ptr noundef dead_on_return [[S:%.*]]) #[[ATTR0]] {
// CHECK-A64-NEXT: [[ENTRY:.*:]]
// CHECK-A64-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
// CHECK-A64-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8

View file

@ -58,7 +58,7 @@ typedef int8_t vec_int8 __attribute__((vector_size(N / 8)));
// CHECK128-NEXT: ret <16 x i8> [[CASTFIXEDSVE]]
// CHECK-LABEL: define{{.*}} void @f2(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 captures(none) initializes((0, [[#div(VBITS,8)]])) %agg.result, ptr dead_on_return noundef readonly captures(none) %0)
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 captures(none) initializes((0, [[#div(VBITS,8)]])) %agg.result, ptr noundef readonly captures(none) dead_on_return %0)
// CHECK-NEXT: entry:
// CHECK-NEXT: [[X:%.*]] = load <[[#div(VBITS,8)]] x i8>, ptr [[TMP0:%.*]], align 16, [[TBAA6:!tbaa !.*]]
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = tail call <vscale x 16 x i8> @llvm.vector.insert.nxv16i8.v[[#div(VBITS,8)]]i8(<vscale x 16 x i8> poison, <[[#div(VBITS,8)]] x i8> [[X]], i64 0)
@ -88,13 +88,13 @@ typedef svint8_t vec2 __attribute__((arm_sve_vector_bits(N)));
// CHECK-NEXT: [[X:%.*]] = tail call <[[#div(VBITS,8)]] x i8> @llvm.vector.extract.v[[#div(VBITS,8)]]i8.nxv16i8(<vscale x 16 x i8> [[X_COERCE:%.*]], i64 0)
// CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]]
// CHECK-NEXT: store <[[#div(VBITS,8)]] x i8> [[X]], ptr [[INDIRECT_ARG_TEMP]], align 16, [[TBAA6]]
// CHECK-NEXT: call void @f3(ptr dead_on_return noundef nonnull [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]]
// CHECK-NEXT: call void @f3(ptr noundef nonnull dead_on_return [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]]
// CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]]
// CHECK-NEXT: ret void
// CHECK128-LABEL: declare void @f3(<16 x i8> noundef)
// CHECK-LABEL: declare void @f3(
// CHECK-SAME: ptr dead_on_return noundef)
// CHECK-SAME: ptr noundef dead_on_return)
void g(vec2 x) { f3(x); } // OK
#endif

View file

@ -75,7 +75,7 @@ typedef svint16_t vec2 __attribute__((arm_sve_vector_bits(N)));
// CHECKWIDE-NEXT: [[X:%.*]] = tail call <[[#div(VBITS, 16)]] x i16> @llvm.vector.extract.v[[#div(VBITS, 16)]]i16.nxv8i16(<vscale x 8 x i16> [[X_COERCE:%.*]], i64 0)
// CHECKWIDE-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]]
// CHECKWIDE-NEXT: store <[[#div(VBITS, 16)]] x i16> [[X]], ptr [[INDIRECT_ARG_TEMP]], align 16, [[TBAA6:!tbaa !.*]]
// CHECKWIDE-NEXT: call void @_Z1fDv[[#div(VBITS, 16)]]_s(ptr dead_on_return noundef nonnull [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]]
// CHECKWIDE-NEXT: call void @_Z1fDv[[#div(VBITS, 16)]]_s(ptr noundef nonnull dead_on_return [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]]
// CHECKWIDE-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]]
// CHECKWIDE-NEXT: ret void
void g(vec2 x) { f(x); } // OK

View file

@ -26,12 +26,12 @@ void pass_BitInt129(_BitInt(129));
// LA32-NEXT: [[LOADEDV1:%.*]] = trunc i128 [[TMP1]] to i65
// LA32-NEXT: [[STOREDV:%.*]] = sext i65 [[LOADEDV1]] to i128
// LA32-NEXT: store i128 [[STOREDV]], ptr [[BYVAL_TEMP]], align 16
// LA32-NEXT: call void @pass_BitInt65(ptr dead_on_return noundef [[BYVAL_TEMP]])
// LA32-NEXT: call void @pass_BitInt65(ptr noundef dead_on_return [[BYVAL_TEMP]])
// LA32-NEXT: [[TMP2:%.*]] = load i256, ptr [[L129]], align 16
// LA32-NEXT: [[LOADEDV2:%.*]] = trunc i256 [[TMP2]] to i129
// LA32-NEXT: [[STOREDV4:%.*]] = sext i129 [[LOADEDV2]] to i256
// LA32-NEXT: store i256 [[STOREDV4]], ptr [[BYVAL_TEMP3]], align 16
// LA32-NEXT: call void @pass_BitInt129(ptr dead_on_return noundef [[BYVAL_TEMP3]])
// LA32-NEXT: call void @pass_BitInt129(ptr noundef dead_on_return [[BYVAL_TEMP3]])
// LA32-NEXT: ret void
//
// LA64-LABEL: define dso_local void @example_BitInt(
@ -54,7 +54,7 @@ void pass_BitInt129(_BitInt(129));
// LA64-NEXT: [[LOADEDV2:%.*]] = trunc i256 [[TMP2]] to i129
// LA64-NEXT: [[STOREDV:%.*]] = sext i129 [[LOADEDV2]] to i256
// LA64-NEXT: store i256 [[STOREDV]], ptr [[BYVAL_TEMP]], align 16
// LA64-NEXT: call void @pass_BitInt129(ptr dead_on_return noundef [[BYVAL_TEMP]])
// LA64-NEXT: call void @pass_BitInt129(ptr noundef dead_on_return [[BYVAL_TEMP]])
// LA64-NEXT: ret void
//
void example_BitInt(void) {

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
#include <lasxintrin.h>
// CHECK-LABEL: define dso_local void @xvfrecipe_s(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecipe.s(<8 x float> [[_1]])
@ -13,7 +13,7 @@
//
v8f32 xvfrecipe_s(v8f32 _1) { return __lasx_xvfrecipe_s(_1); }
// CHECK-LABEL: define dso_local void @xvfrecipe_d(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecipe.d(<4 x double> [[_1]])
@ -22,7 +22,7 @@ v8f32 xvfrecipe_s(v8f32 _1) { return __lasx_xvfrecipe_s(_1); }
//
v4f64 xvfrecipe_d(v4f64 _1) { return __lasx_xvfrecipe_d(_1); }
// CHECK-LABEL: define dso_local void @xvfrsqrte_s(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrte.s(<8 x float> [[_1]])
@ -31,7 +31,7 @@ v4f64 xvfrecipe_d(v4f64 _1) { return __lasx_xvfrecipe_d(_1); }
//
v8f32 xvfrsqrte_s(v8f32 _1) { return __lasx_xvfrsqrte_s(_1); }
// CHECK-LABEL: define dso_local void @xvfrsqrte_d(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrte.d(<4 x double> [[_1]])

View file

@ -5,7 +5,7 @@ typedef float v8f32 __attribute__((vector_size(32), aligned(32)));
typedef double v4f64 __attribute__((vector_size(32), aligned(32)));
// CHECK-LABEL: define dso_local void @xvfrecipe_s(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrecipe.s(<8 x float> [[_1]])
@ -14,7 +14,7 @@ typedef double v4f64 __attribute__((vector_size(32), aligned(32)));
//
v8f32 xvfrecipe_s(v8f32 _1) { return __builtin_lasx_xvfrecipe_s(_1); }
// CHECK-LABEL: define dso_local void @xvfrecipe_d(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrecipe.d(<4 x double> [[_1]])
@ -23,7 +23,7 @@ v8f32 xvfrecipe_s(v8f32 _1) { return __builtin_lasx_xvfrecipe_s(_1); }
//
v4f64 xvfrecipe_d(v4f64 _1) { return __builtin_lasx_xvfrecipe_d(_1); }
// CHECK-LABEL: define dso_local void @xvfrsqrte_s(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<8 x float>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <8 x float>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x float> @llvm.loongarch.lasx.xvfrsqrte.s(<8 x float> [[_1]])
@ -32,7 +32,7 @@ v4f64 xvfrecipe_d(v4f64 _1) { return __builtin_lasx_xvfrecipe_d(_1); }
//
v8f32 xvfrsqrte_s(v8f32 _1) { return __builtin_lasx_xvfrsqrte_s(_1); }
// CHECK-LABEL: define dso_local void @xvfrsqrte_d(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x double>) align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[_1:%.*]] = load <4 x double>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x double> @llvm.loongarch.lasx.xvfrsqrte.d(<4 x double> [[_1]])

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@ v8i16 test_v8i16(v8i16 x)
return x;
}
// CHECK: define{{.*}} void @test_v16i16(ptr dead_on_unwind noalias writable sret(<16 x i16>) align 32 %agg.result, ptr dead_on_return noundef %0)
// CHECK: define{{.*}} void @test_v16i16(ptr dead_on_unwind noalias writable sret(<16 x i16>) align 32 %agg.result, ptr noundef dead_on_return %0)
v16i16 test_v16i16(v16i16 x)
{
return x;

View file

@ -122,7 +122,7 @@ vbool32_t to_vbool32_t(fixed_bool32_t type) {
}
// CHECK-LABEL: define dso_local <vscale x 2 x i32> @to_vint32m1_t__from_gnu_int32m1_t(
// CHECK-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TYPE:%.*]] = load <8 x i32>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA10:![0-9]+]]
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TYPE]], i64 0)
@ -144,7 +144,7 @@ gnu_int32m1_t from_vint32m1_t__to_gnu_int32m1_t(vint32m1_t type) {
}
// CHECK-LABEL: define dso_local <vscale x 2 x i32> @to_fixed_int32m1_t__from_gnu_int32m1_t(
// CHECK-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TYPE:%.*]] = load <8 x i32>, ptr [[TMP0]], align 32, !tbaa [[CHAR_TBAA10]]
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> poison, <8 x i32> [[TYPE]], i64 0)

View file

@ -143,7 +143,7 @@ _BitInt(32) test_bitint_32_add_default(_BitInt(32) a, _BitInt(32) b) {
// RISCV64-NEXT: ret i65 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_unsigned
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10:![0-9]+]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -155,7 +155,7 @@ _BitInt(32) test_bitint_32_add_default(_BitInt(32) a, _BitInt(32) b) {
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_unsigned
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10:![0-9]+]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -177,7 +177,7 @@ unsigned _BitInt(65) test_bitint_65_add_unsigned(unsigned _BitInt(65) a, unsigne
// RISCV64-NEXT: ret i65 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_signed
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -189,7 +189,7 @@ unsigned _BitInt(65) test_bitint_65_add_unsigned(unsigned _BitInt(65) a, unsigne
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_signed
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -211,7 +211,7 @@ signed _BitInt(65) test_bitint_65_add_signed(signed _BitInt(65) a, signed _BitIn
// RISCV64-NEXT: ret i65 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_default
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -223,7 +223,7 @@ signed _BitInt(65) test_bitint_65_add_signed(signed _BitInt(65) a, signed _BitIn
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_default
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65
@ -246,7 +246,7 @@ _BitInt(65) test_bitint_65_add_default(_BitInt(65) a, _BitInt(65) b) {
// RISCV64-NEXT: ret i77 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_unsigned
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12:![0-9]+]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -258,7 +258,7 @@ _BitInt(65) test_bitint_65_add_default(_BitInt(65) a, _BitInt(65) b) {
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_unsigned
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12:![0-9]+]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -280,7 +280,7 @@ unsigned _BitInt(77) test_bitint_77_add_unsigned(unsigned _BitInt(77) a, unsigne
// RISCV64-NEXT: ret i77 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_signed
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -292,7 +292,7 @@ unsigned _BitInt(77) test_bitint_77_add_unsigned(unsigned _BitInt(77) a, unsigne
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_signed
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -314,7 +314,7 @@ signed _BitInt(77) test_bitint_77_add_signed(signed _BitInt(77) a, signed _BitIn
// RISCV64-NEXT: ret i77 [[ADD]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_default
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12]]
// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -326,7 +326,7 @@ signed _BitInt(77) test_bitint_77_add_signed(signed _BitInt(77) a, signed _BitIn
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_default
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA12]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77
@ -344,7 +344,7 @@ _BitInt(77) test_bitint_77_add_default(_BitInt(77) a, _BitInt(77) b) {
// BitInt(200) tests - requires BitInt larger than 128 bits support
// RISCV64-LABEL: define {{[^@]+}}@test_bitint_200_add_unsigned
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
// RISCV64-NEXT: entry:
// RISCV64-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA10:![0-9]+]]
// RISCV64-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -356,7 +356,7 @@ _BitInt(77) test_bitint_77_add_default(_BitInt(77) a, _BitInt(77) b) {
// RISCV64-NEXT: ret void
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_200_add_unsigned
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14:![0-9]+]]
// RISCV32-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -368,7 +368,7 @@ _BitInt(77) test_bitint_77_add_default(_BitInt(77) a, _BitInt(77) b) {
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_200_add_unsigned
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14:![0-9]+]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -384,7 +384,7 @@ unsigned _BitInt(200) test_bitint_200_add_unsigned(unsigned _BitInt(200) a, unsi
}
// RISCV64-LABEL: define {{[^@]+}}@test_bitint_200_add_signed
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV64-NEXT: entry:
// RISCV64-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV64-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -396,7 +396,7 @@ unsigned _BitInt(200) test_bitint_200_add_unsigned(unsigned _BitInt(200) a, unsi
// RISCV64-NEXT: ret void
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_200_add_signed
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -408,7 +408,7 @@ unsigned _BitInt(200) test_bitint_200_add_unsigned(unsigned _BitInt(200) a, unsi
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_200_add_signed
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -424,7 +424,7 @@ signed _BitInt(200) test_bitint_200_add_signed(signed _BitInt(200) a, signed _Bi
}
// RISCV64-LABEL: define {{[^@]+}}@test_bitint_200_add_default
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV64-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV64-NEXT: entry:
// RISCV64-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV64-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -436,7 +436,7 @@ signed _BitInt(200) test_bitint_200_add_signed(signed _BitInt(200) a, signed _Bi
// RISCV64-NEXT: ret void
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_200_add_default
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -448,7 +448,7 @@ signed _BitInt(200) test_bitint_200_add_signed(signed _BitInt(200) a, signed _Bi
// RISCV32-NEXT: ret void
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_200_add_default
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i256) align 8 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i256 [[TMP2]] to i200
@ -466,7 +466,7 @@ _BitInt(200) test_bitint_200_add_default(_BitInt(200) a, _BitInt(200) b) {
// Float <-> BitInt(200) conversions
// RISCV64-LABEL: define {{[^@]+}}@test_bitint_200_to_float
// RISCV64-SAME: (ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV64-SAME: (ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV64-NEXT: entry:
// RISCV64-NEXT: [[TMP1:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA10]]
// RISCV64-NEXT: [[I:%.*]] = trunc i256 [[TMP1]] to i200
@ -474,7 +474,7 @@ _BitInt(200) test_bitint_200_add_default(_BitInt(200) a, _BitInt(200) b) {
// RISCV64-NEXT: ret float [[CONV]]
//
// RISCV32-LABEL: define {{[^@]+}}@test_bitint_200_to_float
// RISCV32-SAME: (ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV32-SAME: (ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV32-NEXT: entry:
// RISCV32-NEXT: [[TMP1:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32-NEXT: [[I:%.*]] = trunc i256 [[TMP1]] to i200
@ -482,7 +482,7 @@ _BitInt(200) test_bitint_200_add_default(_BitInt(200) a, _BitInt(200) b) {
// RISCV32-NEXT: ret float [[CONV]]
//
// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_200_to_float
// RISCV32_INT128-SAME: (ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV32_INT128-SAME: (ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// RISCV32_INT128-NEXT: entry:
// RISCV32_INT128-NEXT: [[TMP1:%.*]] = load i256, ptr [[TMP0]], align 8, !tbaa [[TBAA14]]
// RISCV32_INT128-NEXT: [[I:%.*]] = trunc i256 [[TMP1]] to i200

View file

@ -75,7 +75,7 @@ struct child3_int64_s : parent3_float_s {
};
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z30float_int64_struct_inheritance14child3_int64_s
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD3_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD3_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
// LP64-LABEL: define dso_local [2 x i64] @_Z30float_int64_struct_inheritance14child3_int64_s
@ -99,7 +99,7 @@ struct child4_double_s : parent4_double_s {
};
// ILP32-ILP32F-LABEL: define dso_local void @_Z32double_double_struct_inheritance15child4_double_s
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD4_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD4_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local { double, double } @_Z32double_double_struct_inheritance15child4_double_s
@ -130,11 +130,11 @@ struct child5_virtual_s : virtual parent5_virtual_s {
};
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
// LP64-LP64F-LP64D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
struct child5_virtual_s int32_float_virtual_struct_inheritance(struct child5_virtual_s a) {

View file

@ -138,7 +138,7 @@ struct st_i32x4x9 {
typedef int __attribute__((vector_size(256))) int32x64_t;
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_too_large(ptr dead_on_return noundef %0)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_too_large(ptr noundef dead_on_return %0)
void __attribute__((riscv_vls_cc)) test_too_large(int32x64_t arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_too_large_256(<vscale x 16 x i32> noundef %arg.coerce)
void __attribute__((riscv_vls_cc(256))) test_too_large_256(int32x64_t arg) {}
@ -173,9 +173,9 @@ void __attribute__((riscv_vls_cc)) test_st_i32x8x2(struct st_i32x8x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", <vscale x 8 x i8>, 2) %arg.target_coerce)
void __attribute__((riscv_vls_cc(256))) test_st_i32x8x2_256(struct st_i32x8x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x64x2(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x64x2(ptr noundef dead_on_return %arg)
void __attribute__((riscv_vls_cc)) test_st_i32x64x2(struct st_i32x64x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x64x2_256(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x64x2_256(ptr noundef dead_on_return %arg)
void __attribute__((riscv_vls_cc(256))) test_st_i32x64x2_256(struct st_i32x64x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", <vscale x 8 x i8>, 3) %arg.target_coerce)
@ -188,9 +188,9 @@ void __attribute__((riscv_vls_cc)) test_st_i32x4x8(struct st_i32x4x8 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x8_256(target("riscv.vector.tuple", <vscale x 4 x i8>, 8) %arg.target_coerce)
void __attribute__((riscv_vls_cc(256))) test_st_i32x4x8_256(struct st_i32x4x8 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x9(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x9(ptr noundef dead_on_return %arg)
void __attribute__((riscv_vls_cc)) test_st_i32x4x9(struct st_i32x4x9 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x9_256(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x9_256(ptr noundef dead_on_return %arg)
void __attribute__((riscv_vls_cc(256))) test_st_i32x4x9_256(struct st_i32x4x9 arg) {}
// CHECK-LLVM-LABEL: define dso_local riscv_vls_cc(128) target("riscv.vector.tuple", <vscale x 8 x i8>, 4) @test_function_prolog_epilog(target("riscv.vector.tuple", <vscale x 8 x i8>, 4) %arg.target_coerce) #0 {

View file

@ -118,7 +118,7 @@ struct st_i32x4x9 {
typedef int __attribute__((vector_size(256))) int32x64_t;
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z14test_too_largeDv64_i(ptr dead_on_return noundef %0)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z14test_too_largeDv64_i(ptr noundef dead_on_return %0)
[[riscv::vls_cc]] void test_too_large(int32x64_t arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z18test_too_large_256Dv64_i(<vscale x 16 x i32> noundef %arg.coerce)
[[riscv::vls_cc(256)]] void test_too_large_256(int32x64_t arg) {}
@ -153,9 +153,9 @@ typedef int __attribute__((vector_size(256))) int32x64_t;
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z19test_st_i32x8x2_25610st_i32x8x2(target("riscv.vector.tuple", <vscale x 8 x i8>, 2) %arg.target_coerce)
[[riscv::vls_cc(256)]] void test_st_i32x8x2_256(struct st_i32x8x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z16test_st_i32x64x211st_i32x64x2(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z16test_st_i32x64x211st_i32x64x2(ptr noundef dead_on_return %arg)
[[riscv::vls_cc]] void test_st_i32x64x2(struct st_i32x64x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z20test_st_i32x64x2_25611st_i32x64x2(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z20test_st_i32x64x2_25611st_i32x64x2(ptr noundef dead_on_return %arg)
[[riscv::vls_cc(256)]] void test_st_i32x64x2_256(struct st_i32x64x2 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z15test_st_i32x4x310st_i32x4x3(target("riscv.vector.tuple", <vscale x 8 x i8>, 3) %arg.target_coerce)
@ -168,7 +168,7 @@ typedef int __attribute__((vector_size(256))) int32x64_t;
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z19test_st_i32x4x8_25610st_i32x4x8(target("riscv.vector.tuple", <vscale x 4 x i8>, 8) %arg.target_coerce)
[[riscv::vls_cc(256)]] void test_st_i32x4x8_256(struct st_i32x4x8 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z15test_st_i32x4x910st_i32x4x9(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @_Z15test_st_i32x4x910st_i32x4x9(ptr noundef dead_on_return %arg)
[[riscv::vls_cc]] void test_st_i32x4x9(struct st_i32x4x9 arg) {}
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z19test_st_i32x4x9_25610st_i32x4x9(ptr dead_on_return noundef %arg)
// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @_Z19test_st_i32x4x9_25610st_i32x4x9(ptr noundef dead_on_return %arg)
[[riscv::vls_cc(256)]] void test_st_i32x4x9_256(struct st_i32x4x9 arg) {}

View file

@ -246,7 +246,7 @@ struct large {
};
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_agg_large
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[X:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[X:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_agg_large(struct large x) {
@ -266,7 +266,7 @@ struct large f_agg_large_ret(int32_t i, int8_t j) {
typedef unsigned char v16i8 __attribute__((vector_size(16)));
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_vec_large_v16i8
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[TMP0:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[TMP0:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_vec_large_v16i8(v16i8 x) {
@ -285,7 +285,7 @@ v16i8 f_vec_large_v16i8_ret(void) {
// if they were passed in registers.
// ILP32-ILP32F-ILP32D-LABEL: define dso_local i32 @f_scalar_stack_1
// ILP32-ILP32F-ILP32D-SAME: (i32 [[A_COERCE:%.*]], [2 x i32] [[B_COERCE:%.*]], i64 [[C_COERCE:%.*]], ptr dead_on_return noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]], i8 noundef signext [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (i32 [[A_COERCE:%.*]], [2 x i32] [[B_COERCE:%.*]], i64 [[C_COERCE:%.*]], ptr noundef dead_on_return [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]], i8 noundef signext [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
@ -343,7 +343,7 @@ struct large f_scalar_stack_6(float a, int64_t b, double c, long double d,
// they would be if passed via registers.
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_agg_stack
// ILP32-ILP32F-ILP32D-SAME: (double noundef [[A:%.*]], i64 noundef [[B:%.*]], double noundef [[C:%.*]], i64 noundef [[D:%.*]], i32 [[E_COERCE:%.*]], [2 x i32] [[F_COERCE:%.*]], i64 [[G_COERCE:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (double noundef [[A:%.*]], i64 noundef [[B:%.*]], double noundef [[C:%.*]], i64 noundef [[D:%.*]], i32 [[E_COERCE:%.*]], [2 x i32] [[F_COERCE:%.*]], i64 [[G_COERCE:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_agg_stack(double a, int64_t b, double c, int64_t d, struct tiny e,
@ -366,7 +366,7 @@ struct double_int8_s { double d; int64_t i; };
struct int_double_s { int a; double b; };
// ILP32-ILP32F-LABEL: define dso_local void @f_int_double_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_int_double_s_arg
@ -482,7 +482,7 @@ struct zbf_double_zbf_s f_ret_zbf_double_zbf_s(void) {
struct double_float_s { double f; float g; };
// ILP32-ILP32F-LABEL: define dso_local void @f_double_double_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_double_s_arg
@ -504,7 +504,7 @@ struct double_double_s f_ret_double_double_s(void) {
}
// ILP32-ILP32F-LABEL: define dso_local void @f_double_float_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_float_s_arg
@ -526,7 +526,7 @@ struct double_float_s f_ret_double_float_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_double_double_s_arg_insufficient_fprs
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_double_double_s_arg_insufficient_fprs(float a, double b, double c, double d,
@ -543,7 +543,7 @@ struct double_int64bf_s { double d; int64_t i : 32; };
struct double_int8_zbf_s { double d; int8_t i; int : 0; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_double_int8_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_double_int8_s_arg(struct double_int8_s a) {}
@ -557,7 +557,7 @@ struct double_int8_s f_ret_double_int8_s(void) {
}
// ILP32-ILP32F-LABEL: define dso_local void @f_double_uint8_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_uint8_s_arg
@ -579,7 +579,7 @@ struct double_uint8_s f_ret_double_uint8_s(void) {
}
// ILP32-ILP32F-LABEL: define dso_local void @f_double_int32_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_int32_s_arg
@ -601,7 +601,7 @@ struct double_int32_s f_ret_double_int32_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_double_int64_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_double_int64_s_arg(struct double_int64_s a) {}
@ -615,7 +615,7 @@ struct double_int64_s f_ret_double_int64_s(void) {
}
// ILP32-ILP32F-LABEL: define dso_local void @f_double_int64bf_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_int64bf_s_arg
@ -640,7 +640,7 @@ struct double_int64bf_s f_ret_double_int64bf_s(void) {
// floating point calling convention.
// ILP32-ILP32F-LABEL: define dso_local void @f_double_int8_zbf_s
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_int8_zbf_s
@ -662,14 +662,14 @@ struct double_int8_zbf_s f_ret_double_int8_zbf_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_double_int8_s_arg_insufficient_gprs
// ILP32-ILP32F-ILP32D-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], i32 noundef [[H:%.*]], ptr dead_on_return noundef [[I:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], i32 noundef [[H:%.*]], ptr noundef dead_on_return [[I:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_double_int8_s_arg_insufficient_gprs(int a, int b, int c, int d, int e,
int f, int g, int h, struct double_int8_s i) {}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_struct_double_int8_insufficient_fprs
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], ptr dead_on_return noundef [[I:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], ptr noundef dead_on_return [[I:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double d,
@ -679,7 +679,7 @@ void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double
// floating-point value should be passed as if it were an fp+fp struct.
// ILP32-ILP32F-LABEL: define dso_local void @f_doublecomplex
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublecomplex
@ -703,7 +703,7 @@ double __complex__ f_ret_doublecomplex(void) {
struct doublecomplex_s { double __complex__ c; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublecomplex_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublecomplex_s_arg
@ -754,7 +754,7 @@ struct doublearr1_s f_ret_doublearr1_s(void) {
struct doublearr2_s { double a[2]; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublearr2_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublearr2_s_arg
@ -778,7 +778,7 @@ struct doublearr2_s f_ret_doublearr2_s(void) {
struct doublearr2_tricky1_s { struct { double f[1]; } g[2]; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublearr2_tricky1_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublearr2_tricky1_s_arg
@ -802,7 +802,7 @@ struct doublearr2_tricky1_s f_ret_doublearr2_tricky1_s(void) {
struct doublearr2_tricky2_s { struct {}; struct { double f[1]; } g[2]; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublearr2_tricky2_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublearr2_tricky2_s_arg
@ -826,7 +826,7 @@ struct doublearr2_tricky2_s f_ret_doublearr2_tricky2_s(void) {
struct doublearr2_tricky3_s { union {}; struct { double f[1]; } g[2]; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublearr2_tricky3_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublearr2_tricky3_s_arg
@ -850,7 +850,7 @@ struct doublearr2_tricky3_s f_ret_doublearr2_tricky3_s(void) {
struct doublearr2_tricky4_s { union {}; struct { struct {}; double f[1]; } g[2]; };
// ILP32-ILP32F-LABEL: define dso_local void @f_doublearr2_tricky4_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_doublearr2_tricky4_s_arg
@ -877,7 +877,7 @@ struct doublearr2_tricky4_s f_ret_doublearr2_tricky4_s(void) {
struct int_double_int_s { int a; double b; int c; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int_double_int_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int_double_int_s_arg(struct int_double_int_s a) {}
@ -893,7 +893,7 @@ struct int_double_int_s f_ret_int_double_int_s(void) {
struct int64_double_s { int64_t a; double b; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int64_double_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int64_double_s_arg(struct int64_double_s a) {}
@ -909,7 +909,7 @@ struct int64_double_s f_ret_int64_double_s(void) {
struct char_char_double_s { char a; char b; double c; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_char_char_double_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_char_char_double_s_arg(struct char_char_double_s a) {}
@ -948,7 +948,7 @@ union double_u f_ret_double_u(void) {
// double+double structs by the ABI.
// ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local { double, i32 } @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs
@ -961,7 +961,7 @@ struct double_int32_s f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(
}
// ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local { double, double } @f_ret_double_double_s_double_int32_s_just_sufficient_gprs
@ -974,7 +974,7 @@ struct double_double_s f_ret_double_double_s_double_int32_s_just_sufficient_gprs
}
// ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local { double, double } @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs
@ -1189,7 +1189,7 @@ struct float_int32_s f_ret_float_int32_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_float_int64_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_float_int64_s_arg(struct float_int64_s a) {}
@ -1465,7 +1465,7 @@ struct floatarr2_tricky4_s f_ret_floatarr2_tricky4_s(void) {
struct int_float_int_s { int a; float b; int c; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int_float_int_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int_float_int_s_arg(struct int_float_int_s a) {}
@ -1481,7 +1481,7 @@ struct int_float_int_s f_ret_int_float_int_s(void) {
struct int64_float_s { int64_t a; float b; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int64_float_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int64_float_s_arg(struct int64_float_s a) {}
@ -1619,7 +1619,7 @@ struct zbf_float16_zbf_s f_ret_zbf_float16_zbf_s(void) {
struct double_float16_s { double f; _Float16 g; };
// ILP32-ILP32F-LABEL: define dso_local void @f_double_float16_s_arg
// ILP32-ILP32F-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F: entry:
//
// ILP32D-LABEL: define dso_local void @f_double_float16_s_arg
@ -1641,7 +1641,7 @@ struct double_float16_s f_ret_double_float16_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_double_float16_s_arg_insufficient_fprs
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], ptr dead_on_return noundef [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], ptr noundef dead_on_return [[H:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_double_float16_s_arg_insufficient_fprs(float a, double b, double c, double d,
@ -1725,7 +1725,7 @@ struct float16_int32_s f_ret_float16_int32_s(void) {
}
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_float16_int64_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_float16_int64_s_arg(struct float16_int64_s a) {}
@ -2001,7 +2001,7 @@ struct float16arr2_tricky4_s f_ret_float16arr2_tricky4_s(void) {
struct int_float16_int_s { int a; _Float16 b; int c; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int_float16_int_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int_float16_int_s_arg(struct int_float16_int_s a) {}
@ -2017,7 +2017,7 @@ struct int_float16_int_s f_ret_int_float16_int_s(void) {
struct int64_float16_s { int64_t a; _Float16 b; };
// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_int64_float16_s_arg
// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
void f_int64_float16_s_arg(struct int64_float16_s a) {}

View file

@ -64,7 +64,7 @@ int f_va_callee(int, ...);
// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SMALL_ALIGNED]], ptr [[DOTCOMPOUNDLITERAL4]], i32 0, i32 0
// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[COERCE_DIVE]], align 8
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[BYVAL_TEMP]], ptr align 4 [[DOTCOMPOUNDLITERAL6]], i32 16, i1 false)
// CHECK-NEXT: [[CALL:%.*]] = call i32 (i32, ...) @f_va_callee(i32 noundef 1, i32 noundef 2, i64 noundef 3, double noundef 4.000000e+00, double noundef 5.000000e+00, i32 [[TMP0]], [2 x i32] [[TMP1]], i64 [[TMP2]], ptr dead_on_return noundef [[BYVAL_TEMP]])
// CHECK-NEXT: [[CALL:%.*]] = call i32 (i32, ...) @f_va_callee(i32 noundef 1, i32 noundef 2, i64 noundef 3, double noundef 4.000000e+00, double noundef 5.000000e+00, i32 [[TMP0]], [2 x i32] [[TMP1]], i64 [[TMP2]], ptr noundef dead_on_return [[BYVAL_TEMP]])
// CHECK-NEXT: ret void
//
void f_va_caller(void) {

View file

@ -242,7 +242,7 @@ struct large {
};
// LP64-LP64F-LP64D-LABEL: define dso_local void @f_agg_large
// LP64-LP64F-LP64D-SAME: (ptr dead_on_return noundef [[X:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr noundef dead_on_return [[X:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
void f_agg_large(struct large x) {
@ -262,7 +262,7 @@ struct large f_agg_large_ret(int32_t i, int8_t j) {
typedef unsigned char v32i8 __attribute__((vector_size(32)));
// LP64-LP64F-LP64D-LABEL: define dso_local void @f_vec_large_v32i8
// LP64-LP64F-LP64D-SAME: (ptr dead_on_return noundef [[TMP0:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr noundef dead_on_return [[TMP0:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
void f_vec_large_v32i8(v32i8 x) {
@ -281,7 +281,7 @@ v32i8 f_vec_large_v32i8_ret(void) {
// if they were passed in registers.
// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_1
// LP64-LP64F-LP64D-SAME: (i64 [[A_COERCE:%.*]], [2 x i64] [[B_COERCE:%.*]], i128 [[C_COERCE:%.*]], ptr dead_on_return noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]], i8 noundef signext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (i64 [[A_COERCE:%.*]], [2 x i64] [[B_COERCE:%.*]], i128 [[C_COERCE:%.*]], ptr noundef dead_on_return [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]], i8 noundef signext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
@ -290,7 +290,7 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
}
// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_2
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr dead_on_return noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef dead_on_return [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
int f_scalar_stack_2(int32_t a, __int128_t b, int64_t c, long double d, v32i8 e,
@ -299,7 +299,7 @@ int f_scalar_stack_2(int32_t a, __int128_t b, int64_t c, long double d, v32i8 e,
}
// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_3
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr dead_on_return noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef dead_on_return [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
int f_scalar_stack_3(int32_t a, __int128_t b, double c, long double d, v32i8 e,
@ -312,7 +312,7 @@ int f_scalar_stack_3(int32_t a, __int128_t b, double c, long double d, v32i8 e,
// to pass a pointer.
// LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_4
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr dead_on_return noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef dead_on_return [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
struct large f_scalar_stack_4(uint32_t a, __int128_t b, long double c, v32i8 d,
@ -321,7 +321,7 @@ struct large f_scalar_stack_4(uint32_t a, __int128_t b, long double c, v32i8 d,
}
// LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_5
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr dead_on_return noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef dead_on_return [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
struct large f_scalar_stack_5(double a, __int128_t b, long double c, v32i8 d,
@ -330,7 +330,7 @@ struct large f_scalar_stack_5(double a, __int128_t b, long double c, v32i8 d,
}
// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_6
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], float noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr dead_on_return noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]], half noundef [[I:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], float noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef dead_on_return [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]], half noundef [[I:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
int f_scalar_stack_6(int32_t a, __int128_t b, float c, long double d, v32i8 e,
@ -1440,7 +1440,7 @@ struct doublearr2_tricky4_s f_ret_doublearr2_tricky4_s(void) {
struct int_double_int_s { int a; double b; int c; };
// LP64-LP64F-LP64D-LABEL: define dso_local void @f_int_double_int_s_arg
// LP64-LP64F-LP64D-SAME: (ptr dead_on_return noundef [[A:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D-SAME: (ptr noundef dead_on_return [[A:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
void f_int_double_int_s_arg(struct int_double_int_s a) {}

View file

@ -74,7 +74,7 @@ int f_va_callee(int, ...);
// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SMALL_ALIGNED]], ptr [[DOTCOMPOUNDLITERAL4]], i32 0, i32 0
// CHECK-NEXT: [[TMP2:%.*]] = load i128, ptr [[COERCE_DIVE]], align 16
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[BYVAL_TEMP]], ptr align 8 [[DOTCOMPOUNDLITERAL6]], i64 32, i1 false)
// CHECK-NEXT: [[CALL:%.*]] = call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double noundef 4.000000e+00, double noundef 5.000000e+00, i64 [[TMP0]], [2 x i64] [[TMP1]], i128 [[TMP2]], ptr dead_on_return noundef [[BYVAL_TEMP]])
// CHECK-NEXT: [[CALL:%.*]] = call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double noundef 4.000000e+00, double noundef 5.000000e+00, i64 [[TMP0]], [2 x i64] [[TMP1]], i128 [[TMP2]], ptr noundef dead_on_return [[BYVAL_TEMP]])
// CHECK-NEXT: [[CALL11:%.*]] = call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, fp128 noundef 0xL00000000000000004001400000000000, i32 noundef signext 6, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9)
// CHECK-NEXT: [[A13:%.*]] = getelementptr inbounds nuw [[STRUCT_SMALL_ALIGNED]], ptr [[DOTCOMPOUNDLITERAL12]], i32 0, i32 0
// CHECK-NEXT: store i128 5, ptr [[A13]], align 16

View file

@ -108,14 +108,14 @@ struct medium_aligned {
int *b, *c, *d;
};
// CHECK-LABEL: define{{.*}} %struct.medium @f_medium(ptr dead_on_return noundef %x)
// CHECK-LABEL: define{{.*}} %struct.medium @f_medium(ptr noundef dead_on_return %x)
struct medium f_medium(struct medium x) {
x.a += *x.b;
x.b = 0;
return x;
}
// CHECK-LABEL: define{{.*}} %struct.medium_aligned @f_medium_aligned(ptr dead_on_return noundef %x)
// CHECK-LABEL: define{{.*}} %struct.medium_aligned @f_medium_aligned(ptr noundef dead_on_return %x)
struct medium_aligned f_medium_aligned(struct medium_aligned x) {
x.a += *x.b;
x.b = 0;
@ -129,7 +129,7 @@ struct large {
int x;
};
// CHECK-LABEL: define{{.*}} void @f_large(ptr dead_on_unwind noalias writable sret(%struct.large) align 8 %agg.result, ptr dead_on_return noundef %x)
// CHECK-LABEL: define{{.*}} void @f_large(ptr dead_on_unwind noalias writable sret(%struct.large) align 8 %agg.result, ptr noundef dead_on_return %x)
struct large f_large(struct large x) {
x.a += *x.b;
x.b = 0;

View file

@ -224,7 +224,7 @@ __int128 f17() {
// Test that a statement expression compiles.
// CHECK-LABEL: define dso_local void @f18(
// CHECK-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[T_ADDR:%.*]] = alloca i128, align 8
// CHECK-NEXT: [[T:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[__INT128_TBAA6]]

View file

@ -131,7 +131,7 @@ double test_f64(double f, double g) {
long double test_f128(long double f, long double g) {
asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
return f;
// CHECK: define{{.*}} void @test_f128(ptr dead_on_unwind noalias writable writeonly sret(fp128) align 8 captures(none) initializes((0, 16)) [[DEST:%.*]], ptr dead_on_return noundef readonly captures(none) %0, ptr dead_on_return noundef readonly captures(none) %1)
// CHECK: define{{.*}} void @test_f128(ptr dead_on_unwind noalias writable writeonly sret(fp128) align 8 captures(none) initializes((0, 16)) [[DEST:%.*]], ptr noundef readonly captures(none) dead_on_return %0, ptr noundef readonly captures(none) dead_on_return %1)
// CHECK: %f = load fp128, ptr %0
// CHECK: %g = load fp128, ptr %1
// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)

View file

@ -1064,7 +1064,7 @@ _Complex _Float16 mulf16(_Complex _Float16 a, _Complex _Float16 b) {
// PRMTD-NEXT: ret <2 x half> [[TMP33]]
//
// X86WINPRMTD-LABEL: define dso_local i32 @f1(
// X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], ptr dead_on_return noundef [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], ptr noundef dead_on_return [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2

View file

@ -72,10 +72,10 @@ void receive_vec_512(__m512 x, __m512 y, __m512 z, __m512 w, __m512 q) {
void receive_vec_1024(__m1024 x, __m1024 y, __m1024 z, __m1024 w, __m1024 q) {
gv1024 = x + y + z + w + q;
}
// CHECK-LABEL: define dso_local void @receive_vec_128(<4 x float> inreg noundef %x, <4 x float> inreg noundef %y, <4 x float> inreg noundef %z, ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// CHECK-LABEL: define dso_local void @receive_vec_256(<8 x float> inreg noundef %x, <8 x float> inreg noundef %y, <8 x float> inreg noundef %z, ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// CHECK-LABEL: define dso_local void @receive_vec_512(<16 x float> inreg noundef %x, <16 x float> inreg noundef %y, <16 x float> inreg noundef %z, ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// CHECK-LABEL: define dso_local void @receive_vec_1024(ptr dead_on_return noundef %0, ptr dead_on_return noundef %1, ptr dead_on_return noundef %2, ptr dead_on_return noundef %3, ptr dead_on_return noundef %4)
// CHECK-LABEL: define dso_local void @receive_vec_128(<4 x float> inreg noundef %x, <4 x float> inreg noundef %y, <4 x float> inreg noundef %z, ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
// CHECK-LABEL: define dso_local void @receive_vec_256(<8 x float> inreg noundef %x, <8 x float> inreg noundef %y, <8 x float> inreg noundef %z, ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
// CHECK-LABEL: define dso_local void @receive_vec_512(<16 x float> inreg noundef %x, <16 x float> inreg noundef %y, <16 x float> inreg noundef %z, ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
// CHECK-LABEL: define dso_local void @receive_vec_1024(ptr noundef dead_on_return %0, ptr noundef dead_on_return %1, ptr noundef dead_on_return %2, ptr noundef dead_on_return %3, ptr noundef dead_on_return %4)
void pass_vec_128(void) {
__m128 z = {0};
@ -83,13 +83,13 @@ void pass_vec_128(void) {
}
// CHECK-LABEL: define dso_local void @pass_vec_128()
// CHECK: call void @receive_vec_128(<4 x float> inreg noundef %{{[^,)]*}}, <4 x float> inreg noundef %{{[^,)]*}}, <4 x float> inreg noundef %{{[^,)]*}}, ptr dead_on_return noundef %{{[^,)]*}}, ptr dead_on_return noundef %{{[^,)]*}})
// CHECK: call void @receive_vec_128(<4 x float> inreg noundef %{{[^,)]*}}, <4 x float> inreg noundef %{{[^,)]*}}, <4 x float> inreg noundef %{{[^,)]*}}, ptr noundef dead_on_return %{{[^,)]*}}, ptr noundef dead_on_return %{{[^,)]*}})
void __fastcall fastcall_indirect_vec(__m128 x, __m128 y, __m128 z, __m128 w, int edx, __m128 q) {
gv128 = x + y + z + w + q;
}
// CHECK-LABEL: define dso_local x86_fastcallcc void @"\01@fastcall_indirect_vec@84"(<4 x float> inreg noundef %x, <4 x float> inreg noundef %y, <4 x float> inreg noundef %z, ptr dead_on_return inreg noundef %0, i32 inreg noundef %edx, ptr dead_on_return noundef %1)
// CHECK-LABEL: define dso_local x86_fastcallcc void @"\01@fastcall_indirect_vec@84"(<4 x float> inreg noundef %x, <4 x float> inreg noundef %y, <4 x float> inreg noundef %z, ptr inreg noundef dead_on_return %0, i32 inreg noundef %edx, ptr noundef dead_on_return %1)
struct __declspec(align(1)) Align1 { unsigned long long x; };
struct __declspec(align(4)) Align4 { unsigned long long x; };
@ -156,4 +156,4 @@ void pass_fixed_align_variadic() {
// correctly in Clang than it is to be bug for bug compatible, so we pass such
// arguments indirectly.
// CHECK-LABEL: define dso_local void @pass_fixed_align_variadic()
// CHECK: call void (ptr, ...) @receive_fixed_align_variadic(ptr dead_on_return noundef %{{[^)]*}}, i32 noundef 42)
// CHECK: call void (ptr, ...) @receive_fixed_align_variadic(ptr noundef dead_on_return %{{[^)]*}}, i32 noundef 42)

View file

@ -21,7 +21,7 @@ void f4(unsigned short a) {}
// CHECK-LABEL: define dso_local void @f5(i64 noundef %a.coerce)
void f5(_Complex float a) {}
// CHECK-LABEL: define dso_local void @f6(ptr dead_on_return noundef %a)
// CHECK-LABEL: define dso_local void @f6(ptr noundef dead_on_return %a)
void f6(_Complex double a) {}
// CHECK-LABEL: define dso_local i64 @f7()

View file

@ -122,8 +122,8 @@ unsigned sizeof_RidiculouslyOverSizedBitfield = sizeof(RidiculouslyOverSizedBitf
unsigned alignof_RidiculouslyOverSizedBitfield = alignof(RidiculouslyOverSizedBitfield);
// CHECK: define{{.*}} void @g9
// CHECK: call void @f9(i32 noundef 1, ptr dead_on_return noundef nonnull %agg.tmp)
// CHECK: declare void @f9(i32 noundef, ptr dead_on_return noundef)
// CHECK: call void @f9(i32 noundef 1, ptr noundef nonnull dead_on_return %agg.tmp)
// CHECK: declare void @f9(i32 noundef, ptr noundef dead_on_return)
void f9(int a, RidiculouslyOverSizedBitfield b);
void g9() {
RidiculouslyOverSizedBitfield s = {42};

View file

@ -65,7 +65,7 @@ struct big_struct {
float f4;
};
// CHECK: define{{.*}} arm_aapcs_vfpcc void @test_big([5 x i32] %{{.*}})
// CHECK64: define{{.*}} void @test_big(ptr dead_on_return noundef %{{.*}})
// CHECK64: define{{.*}} void @test_big(ptr noundef dead_on_return %{{.*}})
// CHECK64: call void @llvm.memcpy
// CHECK64: call void @big_callee(ptr
extern void big_callee(struct big_struct);

View file

@ -177,11 +177,11 @@ double varargs_vec_19c(int fixed, ...) {
double test_19c(__char19 *in) {
// CHECK: test_19c
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})
// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef dead_on_return {{%.*}})
// APCS-GNU: test_19c
// APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})
// APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef dead_on_return {{%.*}})
// ANDROID: test_19c
// ANDROID: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})
// ANDROID: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef dead_on_return {{%.*}})
return varargs_vec_19c(19, *in);
}

View file

@ -128,7 +128,7 @@ double varargs_vec_19c(int fixed, ...) {
double test_19c(__char19 *in) {
// CHECK: test_19c
// CHECK: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})
// CHECK: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr noundef dead_on_return {{%.*}})
return varargs_vec_19c(19, *in);
}
@ -211,7 +211,7 @@ double varargs_vec_5i(int fixed, ...) {
double test_5i(__int5 *in) {
// CHECK: test_5i
// CHECK: call double (i32, ...) @varargs_vec_5i(i32 noundef 5, ptr dead_on_return noundef {{%.*}})
// CHECK: call double (i32, ...) @varargs_vec_5i(i32 noundef 5, ptr noundef dead_on_return {{%.*}})
return varargs_vec_5i(5, *in);
}
@ -231,7 +231,7 @@ double varargs_vec_3d(int fixed, ...) {
double test_3d(__double3 *in) {
// CHECK: test_3d
// CHECK: call double (i32, ...) @varargs_vec_3d(i32 noundef 3, ptr dead_on_return noundef {{%.*}})
// CHECK: call double (i32, ...) @varargs_vec_3d(i32 noundef 3, ptr noundef dead_on_return {{%.*}})
return varargs_vec_3d(3, *in);
}
@ -291,7 +291,7 @@ double test(__char3 *c3, __char5 *c5, __char9 *c9, __char19 *c19,
__short3 *s3, __short5 *s5, __int3 *i3, __int5 *i5,
__double3 *d3) {
double ret = varargs_vec(3, *c3, *c5, *c9, *c19, *s3, *s5, *i3, *i5, *d3);
// CHECK: call double (i32, ...) @varargs_vec(i32 noundef 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, ptr dead_on_return noundef {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, ptr dead_on_return noundef {{%.*}}, ptr dead_on_return noundef {{%.*}})
// CHECK: call double (i32, ...) @varargs_vec(i32 noundef 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, ptr noundef dead_on_return {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, ptr noundef dead_on_return {{%.*}}, ptr noundef dead_on_return {{%.*}})
return ret;
}
@ -350,7 +350,7 @@ __attribute__((noinline)) double args_vec_19c(int fixed, __char19 c19) {
double fixed_19c(__char19 *in) {
// CHECK: fixed_19c
// CHECK: call double @args_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})
// CHECK: call double @args_vec_19c(i32 noundef 19, ptr noundef dead_on_return {{%.*}})
return args_vec_19c(19, *in);
}
@ -409,7 +409,7 @@ __attribute__((noinline)) double args_vec_5i(int fixed, __int5 c5) {
double fixed_5i(__int5 *in) {
// CHECK: fixed_5i
// CHECK: call double @args_vec_5i(i32 noundef 5, ptr dead_on_return noundef {{%.*}})
// CHECK: call double @args_vec_5i(i32 noundef 5, ptr noundef dead_on_return {{%.*}})
return args_vec_5i(5, *in);
}
@ -424,6 +424,6 @@ __attribute__((noinline)) double args_vec_3d(int fixed, __double3 c3) {
double fixed_3d(__double3 *in) {
// CHECK: fixed_3d
// CHECK: call double @args_vec_3d(i32 noundef 3, ptr dead_on_return noundef {{%.*}})
// CHECK: call double @args_vec_3d(i32 noundef 3, ptr noundef dead_on_return {{%.*}})
return args_vec_3d(3, *in);
}

View file

@ -163,7 +163,7 @@ void f32(struct s32 s) { }
// A composite type larger than 16 bytes should be passed indirectly.
struct s33 { char buf[32*32]; };
void f33(struct s33 s) { }
// CHECK: define{{.*}} void @f33(ptr dead_on_return noundef %s)
// CHECK: define{{.*}} void @f33(ptr noundef dead_on_return %s)
struct s34 { char c; };
void f34(struct s34 s);
@ -226,9 +226,9 @@ T_float32x2 f1_0(T_float32x2 a0) { return a0; }
// CHECK: define{{.*}} <4 x float> @f1_1(<4 x float> noundef %{{.*}})
T_float32x4 f1_1(T_float32x4 a0) { return a0; }
// Vector with length bigger than 16-byte is illegal and is passed indirectly.
// CHECK: define{{.*}} void @f1_2(ptr dead_on_unwind noalias writable sret(<8 x float>) align 16 %{{.*}}, ptr dead_on_return noundef %0)
// CHECK: define{{.*}} void @f1_2(ptr dead_on_unwind noalias writable sret(<8 x float>) align 16 %{{.*}}, ptr noundef dead_on_return %0)
T_float32x8 f1_2(T_float32x8 a0) { return a0; }
// CHECK: define{{.*}} void @f1_3(ptr dead_on_unwind noalias writable sret(<16 x float>) align 16 %{{.*}}, ptr dead_on_return noundef %0)
// CHECK: define{{.*}} void @f1_3(ptr dead_on_unwind noalias writable sret(<16 x float>) align 16 %{{.*}}, ptr noundef dead_on_return %0)
T_float32x16 f1_3(T_float32x16 a0) { return a0; }
// Testing alignment with aggregates: HFA, aggregates with size <= 16 bytes and
@ -278,7 +278,7 @@ struct s37
typedef struct s37 s37_with_align;
int32x4_t f37(int i, s37_with_align s1, s37_with_align s2) {
// CHECK: define{{.*}} <4 x i32> @f37(i32 noundef %i, ptr dead_on_return noundef %s1, ptr dead_on_return noundef %s2)
// CHECK: define{{.*}} <4 x i32> @f37(i32 noundef %i, ptr noundef dead_on_return %s1, ptr noundef dead_on_return %s2)
// CHECK: load <4 x i32>, ptr %s1, align 16
// CHECK: load <4 x i32>, ptr %s2, align 16
int32x4_t v = vaddq_s32(*(int32x4_t *)&s1,
@ -292,7 +292,7 @@ int32x4_t caller37() {
// CHECK: %[[b:.*]] = alloca %struct.s37, align 16
// CHECK: call void @llvm.memcpy
// CHECK: call void @llvm.memcpy
// CHECK: call <4 x i32> @f37(i32 noundef 3, ptr dead_on_return noundef %[[a]], ptr dead_on_return noundef %[[b]])
// CHECK: call <4 x i32> @f37(i32 noundef 3, ptr noundef dead_on_return %[[a]], ptr noundef dead_on_return %[[b]])
return f37(3, g37, g37);
}
@ -530,7 +530,7 @@ typedef struct s42 s42_no_align;
// passing structs in registers
__attribute__ ((noinline))
int f42(int i, s42_no_align s1, s42_no_align s2) {
// CHECK: define{{.*}} i32 @f42(i32 noundef %i, ptr dead_on_return noundef %s1, ptr dead_on_return noundef %s2)
// CHECK: define{{.*}} i32 @f42(i32 noundef %i, ptr noundef dead_on_return %s1, ptr noundef dead_on_return %s2)
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s1, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s2, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s1, i32 0, i32 1
@ -545,14 +545,14 @@ int caller42() {
// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call i32 @f42(i32 noundef 3, ptr dead_on_return noundef %[[a]], ptr dead_on_return noundef %[[b]])
// CHECK: call i32 @f42(i32 noundef 3, ptr noundef dead_on_return %[[a]], ptr noundef dead_on_return %[[b]])
return f42(3, g42, g42_2);
}
// passing structs on stack
__attribute__ ((noinline))
int f42_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
int i9, s42_no_align s1, s42_no_align s2) {
// CHECK: define{{.*}} i32 @f42_stack(i32 noundef %i, i32 noundef %i2, i32 noundef %i3, i32 noundef %i4, i32 noundef %i5, i32 noundef %i6, i32 noundef %i7, i32 noundef %i8, i32 noundef %i9, ptr dead_on_return noundef %s1, ptr dead_on_return noundef %s2)
// CHECK: define{{.*}} i32 @f42_stack(i32 noundef %i, i32 noundef %i2, i32 noundef %i3, i32 noundef %i4, i32 noundef %i5, i32 noundef %i6, i32 noundef %i7, i32 noundef %i8, i32 noundef %i9, ptr noundef dead_on_return %s1, ptr noundef dead_on_return %s2)
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s1, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s2, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s42, ptr %s1, i32 0, i32 1
@ -565,7 +565,7 @@ int caller42_stack() {
// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call i32 @f42_stack(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, i32 noundef 6, i32 noundef 7, i32 noundef 8, i32 noundef 9, ptr dead_on_return noundef %[[a]], ptr dead_on_return noundef %[[b]])
// CHECK: call i32 @f42_stack(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, i32 noundef 6, i32 noundef 7, i32 noundef 8, i32 noundef 9, ptr noundef dead_on_return %[[a]], ptr noundef dead_on_return %[[b]])
return f42_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g42, g42_2);
}
@ -583,7 +583,7 @@ typedef struct s43 s43_with_align;
// passing aligned structs in registers
__attribute__ ((noinline))
int f43(int i, s43_with_align s1, s43_with_align s2) {
// CHECK: define{{.*}} i32 @f43(i32 noundef %i, ptr dead_on_return noundef %s1, ptr dead_on_return noundef %s2)
// CHECK: define{{.*}} i32 @f43(i32 noundef %i, ptr noundef dead_on_return %s1, ptr noundef dead_on_return %s2)
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s1, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s2, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s1, i32 0, i32 1
@ -598,14 +598,14 @@ int caller43() {
// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call i32 @f43(i32 noundef 3, ptr dead_on_return noundef %[[a]], ptr dead_on_return noundef %[[b]])
// CHECK: call i32 @f43(i32 noundef 3, ptr noundef dead_on_return %[[a]], ptr noundef dead_on_return %[[b]])
return f43(3, g43, g43_2);
}
// passing aligned structs on stack
__attribute__ ((noinline))
int f43_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
int i9, s43_with_align s1, s43_with_align s2) {
// CHECK: define{{.*}} i32 @f43_stack(i32 noundef %i, i32 noundef %i2, i32 noundef %i3, i32 noundef %i4, i32 noundef %i5, i32 noundef %i6, i32 noundef %i7, i32 noundef %i8, i32 noundef %i9, ptr dead_on_return noundef %s1, ptr dead_on_return noundef %s2)
// CHECK: define{{.*}} i32 @f43_stack(i32 noundef %i, i32 noundef %i2, i32 noundef %i3, i32 noundef %i4, i32 noundef %i5, i32 noundef %i6, i32 noundef %i7, i32 noundef %i8, i32 noundef %i9, ptr noundef dead_on_return %s1, ptr noundef dead_on_return %s2)
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s1, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s2, i32 0, i32 0
// CHECK: getelementptr inbounds nuw %struct.s43, ptr %s1, i32 0, i32 1
@ -618,7 +618,7 @@ int caller43_stack() {
// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call void @llvm.memcpy.p0.p0.i64
// CHECK: call i32 @f43_stack(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, i32 noundef 6, i32 noundef 7, i32 noundef 8, i32 noundef 9, ptr dead_on_return noundef %[[a]], ptr dead_on_return noundef %[[b]])
// CHECK: call i32 @f43_stack(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, i32 noundef 6, i32 noundef 7, i32 noundef 8, i32 noundef 9, ptr noundef dead_on_return %[[a]], ptr noundef dead_on_return %[[b]])
return f43_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g43, g43_2);
}

View file

@ -29,7 +29,7 @@ S2 f2() {
// Pass and return for type size > 16 bytes.
// CHECK: define {{.*}} void @{{.*}}f3{{.*}}(ptr dead_on_unwind noalias writable sret(%struct.S3) align 4 %agg.result)
// CHECK: call void {{.*}}func3{{.*}}(ptr dead_on_unwind writable sret(%struct.S3) align 4 %agg.result, ptr dead_on_return noundef %agg.tmp)
// CHECK: call void {{.*}}func3{{.*}}(ptr dead_on_unwind writable sret(%struct.S3) align 4 %agg.result, ptr noundef dead_on_return %agg.tmp)
struct S3 {
int a[5];
};

View file

@ -74,6 +74,6 @@ void g(A a, B b, C c) { f(a, b, c); }
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[COERCE_DIVE3]], align 4
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[BYVAL_TEMP]], ptr align 1 [[B]], i64 6, i1 false)
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BYVAL_TEMP4]], ptr align 4 [[C]], i64 16, i1 false)
// CHECK-NEXT: call void (i64, ...) @f(i64 [[TMP0]], ptr dead_on_return noundef [[BYVAL_TEMP]], ptr dead_on_return noundef [[BYVAL_TEMP4]])
// CHECK-NEXT: call void (i64, ...) @f(i64 [[TMP0]], ptr noundef dead_on_return [[BYVAL_TEMP]], ptr noundef dead_on_return [[BYVAL_TEMP4]])
// CHECK-NEXT: ret void
//

View file

@ -39,7 +39,7 @@ typedef struct {
double z;
} BigStruct;
// CHECK: define{{.*}} void @big_struct_indirect(ptr dead_on_return noundef %b)
// CHECK: define{{.*}} void @big_struct_indirect(ptr noundef dead_on_return %b)
void big_struct_indirect(BigStruct b) {}
// CHECK: define{{.*}} void @return_big_struct_indirect(ptr dead_on_unwind noalias writable sret

View file

@ -57,7 +57,7 @@ void test3(pointer_pair_t pair) {
}
// CHECK-LABEL:define{{.*}} void @test4(
// CHECK-SAME: ptr dead_on_return noundef [[QUAD:%.*]])
// CHECK-SAME: ptr noundef dead_on_return [[QUAD:%.*]])
// CHECK: [[QUAD_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[TEMP:%.*]] = alloca [[QUAD_T:%.*]], align 8
// CHECK-NEXT: store ptr [[QUAD]], ptr [[QUAD_INDIRECT_ADDR]]

View file

@ -77,7 +77,7 @@ svint64_t lax_cast(fixed_int32_t type) {
}
// CHECK-LABEL: define dso_local <vscale x 4 x i32> @to_svint32_t__from_gnu_int32_t(
// CHECK-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TYPE:%.*]] = load <16 x i32>, ptr [[TMP0]], align 16, !tbaa [[CHAR_TBAA6:![0-9]+]]
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TYPE]], i64 0)
@ -99,7 +99,7 @@ gnu_int32_t from_svint32_t__to_gnu_int32_t(svint32_t type) {
}
// CHECK-LABEL: define dso_local <vscale x 4 x i32> @to_fixed_int32_t__from_gnu_int32_t(
// CHECK-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TYPE:%.*]] = load <16 x i32>, ptr [[TMP0]], align 16, !tbaa [[CHAR_TBAA6]]
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> poison, <16 x i32> [[TYPE]], i64 0)

View file

@ -27,7 +27,7 @@ struct NoCopy {
NoCopy ret_nocopy() { return {}; }
void pass_nocopy(NoCopy e) {}
// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %
// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr dead_on_return noundef %
// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef dead_on_return %
struct Huge {
int a[1024];
@ -36,7 +36,7 @@ Huge ret_huge() { return {}; }
void pass_huge(Huge h) {}
// CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %
// CHECK-INTEL: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef
// CHECK-AARCH: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr dead_on_return noundef
// CHECK-AARCH: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef dead_on_return
} // namespace check_structs
//************ Passing unions by value
@ -60,7 +60,7 @@ union NoCopy {
NoCopy ret_nocopy() { return {}; }
void pass_nocopy(NoCopy e) {}
// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %
// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr dead_on_return noundef %
// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef dead_on_return %
} // namespace check_unions
//************ Passing `this` pointers

View file

@ -1520,7 +1520,7 @@ void mulassignf(_Complex float *a, _Complex float b) {
// PRMTD-NEXT: ret { double, double } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD-LABEL: define dso_local void @divd(
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -1744,7 +1744,7 @@ void mulassignf(_Complex float *a, _Complex float b) {
// PRMTD_FAST-NEXT: ret { double, double } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @divd(
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -1938,7 +1938,7 @@ _Complex double divd(_Complex double a, _Complex double b) {
// PRMTD-NEXT: ret void
//
// X86WINPRMTD-LABEL: define dso_local void @divassignd(
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -2180,7 +2180,7 @@ _Complex double divd(_Complex double a, _Complex double b) {
// PRMTD_FAST-NEXT: ret void
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @divassignd(
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -2325,7 +2325,7 @@ void divassignd(_Complex double *a, _Complex double b) {
// PRMTD-NEXT: ret { double, double } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD-LABEL: define dso_local void @muld(
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -2457,7 +2457,7 @@ void divassignd(_Complex double *a, _Complex double b) {
// PRMTD_FAST-NEXT: ret { double, double } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @muld(
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -2594,7 +2594,7 @@ _Complex double muld(_Complex double a, _Complex double b) {
// PRMTD-NEXT: ret void
//
// X86WINPRMTD-LABEL: define dso_local void @mulassignd(
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -2744,7 +2744,7 @@ _Complex double muld(_Complex double a, _Complex double b) {
// PRMTD_FAST-NEXT: ret void
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulassignd(
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -2922,7 +2922,7 @@ void mulassignd(_Complex double *a, _Complex double b) {
// PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD-LABEL: define dso_local void @divld(
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -3190,7 +3190,7 @@ void mulassignd(_Complex double *a, _Complex double b) {
// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @divld(
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -3432,7 +3432,7 @@ _Complex long double divld(_Complex long double a, _Complex long double b) {
// PRMTD-NEXT: ret void
//
// X86WINPRMTD-LABEL: define dso_local void @divassignld(
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -3702,7 +3702,7 @@ _Complex long double divld(_Complex long double a, _Complex long double b) {
// PRMTD_FAST-NEXT: ret void
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @divassignld(
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -3895,7 +3895,7 @@ void divassignld(_Complex long double *a, _Complex long double b) {
// PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD-LABEL: define dso_local void @mulld(
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -4059,7 +4059,7 @@ void divassignld(_Complex long double *a, _Complex long double b) {
// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]]
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulld(
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr dead_on_return noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef dead_on_return [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
@ -4220,7 +4220,7 @@ _Complex long double mulld(_Complex long double a, _Complex long double b) {
// PRMTD-NEXT: ret void
//
// X86WINPRMTD-LABEL: define dso_local void @mulassignld(
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -4386,7 +4386,7 @@ _Complex long double mulld(_Complex long double a, _Complex long double b) {
// PRMTD_FAST-NEXT: ret void
//
// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulassignld(
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr dead_on_return noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef dead_on_return [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@ -4644,7 +4644,7 @@ void mulassignld(_Complex long double *a, _Complex long double b) {
// PRMTD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]]
//
// X86WINPRMTD-LABEL: define dso_local i64 @f1(
// X86WINPRMTD-SAME: i64 noundef [[A_COERCE:%.*]], ptr dead_on_return noundef [[B:%.*]], i64 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-SAME: i64 noundef [[A_COERCE:%.*]], ptr noundef dead_on_return [[B:%.*]], i64 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD-NEXT: entry:
// X86WINPRMTD-NEXT: [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A_COERCE]] to i32
// X86WINPRMTD-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_SROA_0_0_EXTRACT_TRUNC]] to float
@ -5052,7 +5052,7 @@ void mulassignld(_Complex long double *a, _Complex long double b) {
// PRMTD_FAST-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]]
//
// X86WINPRMTD_STRICT-LABEL: define dso_local i64 @f1(
// X86WINPRMTD_STRICT-SAME: i64 noundef [[A_COERCE:%.*]], ptr dead_on_return noundef [[B:%.*]], i64 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-SAME: i64 noundef [[A_COERCE:%.*]], ptr noundef dead_on_return [[B:%.*]], i64 noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
// X86WINPRMTD_STRICT-NEXT: [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A_COERCE]] to i32
// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_SROA_0_0_EXTRACT_TRUNC]] to float

View file

@ -160,7 +160,7 @@ int4 check_isfpclass_nan_strict_v4f32(float4 x) {
}
// CHECK-LABEL: define dso_local void @check_isfpclass_nan_v4f64(
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x i64>) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<4 x i64>) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[X:%.*]] = load <4 x double>, ptr [[TMP0]], align 16, !tbaa [[CHAR_TBAA6:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = fcmp uno <4 x double> [[X]], zeroinitializer

View file

@ -53,12 +53,12 @@ long double powl(long double a, long double b);
// CHECK-SPIR: [[CALL:%.*]] = tail call spir_func double @powl(double noundef [[A]], double noundef [[B]]) #[[ATTR4:[0-9]+]], !tbaa [[INT_TBAA2:![0-9]+]]
//
// CHECK-MINGW32-LABEL: define dso_local void @test_powl(
// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret(x86_fp80) align 16 captures(none) initializes((0, 10)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret(x86_fp80) align 16 captures(none) initializes((0, 10)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]], ptr noundef readonly captures(none) dead_on_return [[TMP1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-MINGW32: [[A:%.*]] = load x86_fp80, ptr [[TMP0]], align 16, !tbaa [[LONG_DOUBLE_TBAA10:![0-9]+]]
// CHECK-MINGW32: [[B:%.*]] = load x86_fp80, ptr [[TMP1]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: store x86_fp80 [[A]], ptr [[BYVAL_TEMP:%.*]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: store x86_fp80 [[B]], ptr [[BYVAL_TEMP1:%.*]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: call void @powl(ptr dead_on_unwind nonnull writable sret(x86_fp80) align 16 [[TMP:%.*]], ptr dead_on_return noundef nonnull [[BYVAL_TEMP]], ptr dead_on_return noundef nonnull [[BYVAL_TEMP1]]) #[[ATTR3:[0-9]+]]
// CHECK-MINGW32: call void @powl(ptr dead_on_unwind nonnull writable sret(x86_fp80) align 16 [[TMP:%.*]], ptr noundef nonnull dead_on_return [[BYVAL_TEMP]], ptr noundef nonnull dead_on_return [[BYVAL_TEMP1]]) #[[ATTR3:[0-9]+]]
// CHECK-MINGW32: [[TMP2:%.*]] = load x86_fp80, ptr [[TMP]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: store x86_fp80 [[TMP2]], ptr [[AGG_RESULT]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
//
@ -131,12 +131,12 @@ long double test_powl(long double a, long double b) {
// CHECK-SPIR: store double [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 8
//
// CHECK-MINGW32-LABEL: define dso_local void @test_cargl(
// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret({ x86_fp80, x86_fp80 }) align 16 captures(none) initializes((0, 10), (16, 26)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret({ x86_fp80, x86_fp80 }) align 16 captures(none) initializes((0, 10), (16, 26)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) dead_on_return [[CLD:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-MINGW32: [[CLD_REAL:%.*]] = load x86_fp80, ptr [[CLD]], align 16
// CHECK-MINGW32: [[CLD_IMAG:%.*]] = load x86_fp80, ptr [[CLD_IMAGP:%.*]], align 16
// CHECK-MINGW32: store x86_fp80 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16
// CHECK-MINGW32: store x86_fp80 [[CLD_IMAG]], ptr [[BYVAL_TEMP_IMAGP:%.*]], align 16
// CHECK-MINGW32: call void @cargl(ptr dead_on_unwind nonnull writable sret(x86_fp80) align 16 [[TMP:%.*]], ptr dead_on_return noundef nonnull [[BYVAL_TEMP]]) #[[ATTR3]]
// CHECK-MINGW32: call void @cargl(ptr dead_on_unwind nonnull writable sret(x86_fp80) align 16 [[TMP:%.*]], ptr noundef nonnull dead_on_return [[BYVAL_TEMP]]) #[[ATTR3]]
// CHECK-MINGW32: [[TMP0:%.*]] = load x86_fp80, ptr [[TMP]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: [[CLD_REAL3:%.*]] = load x86_fp80, ptr [[CLD]], align 16
// CHECK-MINGW32: [[CLD_IMAG5:%.*]] = load x86_fp80, ptr [[CLD_IMAGP]], align 16
@ -189,10 +189,10 @@ int ilogbl(long double a);
// CHECK-SPIR: [[CALL:%.*]] = tail call spir_func i32 @ilogbl(double noundef [[A]]) #[[ATTR4]], !tbaa [[INT_TBAA2]]
//
// CHECK-MINGW32-LABEL: define dso_local i32 @test_ilogb(
// CHECK-MINGW32-SAME: ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-MINGW32-SAME: ptr noundef readonly captures(none) dead_on_return [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-MINGW32: [[A:%.*]] = load x86_fp80, ptr [[TMP0]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: store x86_fp80 [[A]], ptr [[BYVAL_TEMP:%.*]], align 16, !tbaa [[LONG_DOUBLE_TBAA10]]
// CHECK-MINGW32: [[CALL:%.*]] = call i32 @ilogbl(ptr dead_on_return noundef nonnull [[BYVAL_TEMP]]) #[[ATTR3]]
// CHECK-MINGW32: [[CALL:%.*]] = call i32 @ilogbl(ptr noundef nonnull dead_on_return [[BYVAL_TEMP]]) #[[ATTR3]]
//
int test_ilogb(long double a) {
return ilogbl(a);

View file

@ -29,15 +29,15 @@ long double TestLD(long double x) {
return x * x;
}
// GNU32: define dso_local x86_fp80 @TestLD(x86_fp80 noundef %x)
// GNU64: define dso_local void @TestLD(ptr dead_on_unwind noalias writable sret(x86_fp80) align 16 %agg.result, ptr dead_on_return noundef %0)
// GNU64: define dso_local void @TestLD(ptr dead_on_unwind noalias writable sret(x86_fp80) align 16 %agg.result, ptr noundef dead_on_return %0)
// MSC64: define dso_local double @TestLD(double noundef %x)
long double _Complex TestLDC(long double _Complex x) {
return x * x;
}
// GNU32: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %x)
// GNU64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr dead_on_return noundef %x)
// MSC64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr dead_on_return noundef %x)
// GNU64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef dead_on_return %x)
// MSC64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef dead_on_return %x)
// GNU32: declare dso_local void @__mulxc3
// GNU64: declare dso_local void @__mulxc3

View file

@ -144,7 +144,7 @@ struct i128 {
};
__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
// WIN64: define dso_local void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr dead_on_return noundef %a)
// FREEBSD: define{{.*}} win64cc void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr dead_on_return noundef %a)
// WIN64: define dso_local void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr noundef dead_on_return %a)
// FREEBSD: define{{.*}} win64cc void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr noundef dead_on_return %a)
return a;
}

View file

@ -11,6 +11,6 @@ struct Foo {
int f;
};
// WITH_NOALIAS: define{{.*}} void @take(ptr dead_on_return noalias noundef %arg)
// NO_NOALIAS: define{{.*}} void @take(ptr dead_on_return noundef %arg)
// WITH_NOALIAS: define{{.*}} void @take(ptr noalias noundef dead_on_return %arg)
// NO_NOALIAS: define{{.*}} void @take(ptr noundef dead_on_return %arg)
void take(struct Foo arg) {}

View file

@ -115,7 +115,7 @@ void test_move_assignment_SA(SA *p) {
*p = getSA();
}
// CHECK: define void @test_parameter_SA(ptr dead_on_return noundef %{{.*}})
// CHECK: define void @test_parameter_SA(ptr noundef dead_on_return %{{.*}})
// CHECK-NOT: call
// CHECK: ret void
@ -128,7 +128,7 @@ void test_parameter_SA(SA a) {
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
// CHECK: call void @__copy_constructor_8_8_t0w4_pa1_50_8(ptr %[[AGG_TMP]], ptr %[[V0]])
// CHECK: call void @calleeSA(ptr dead_on_return noundef %[[AGG_TMP]])
// CHECK: call void @calleeSA(ptr noundef dead_on_return %[[AGG_TMP]])
// CHECK-NOT: call
// CHECK: ret void

View file

@ -28,7 +28,7 @@ struct Large { int a[5]; };
void __regcall v4(int a, struct Large b, int c) {}
// Win32: define dso_local x86_regcallcc void @__regcall3__v4(i32 inreg noundef %a, ptr noundef byval(%struct.Large) align 4 %b, i32 inreg noundef %c)
// Lin32: define dso_local x86_regcallcc void @__regcall3__v4(i32 inreg noundef %a, ptr noundef byval(%struct.Large) align 4 %b, i32 noundef %c)
// Win64: define dso_local x86_regcallcc void @__regcall3__v4(i32 noundef %a, ptr dead_on_return noundef %b, i32 noundef %c)
// Win64: define dso_local x86_regcallcc void @__regcall3__v4(i32 noundef %a, ptr noundef dead_on_return %b, i32 noundef %c)
// Lin64: define dso_local x86_regcallcc void @__regcall3__v4(i32 noundef %a, [5 x i32] %b.coerce, i32 noundef %c)
void __regcall v5(long long a, int b, int c) {}
@ -47,7 +47,7 @@ void __regcall hfa1(int a, struct HFA4 b, int c) {}
// indirectly. Additional vector arguments can consume the rest of the SSE
// registers.
void __regcall hfa2(struct HFA4 a, struct HFA4 b, double c) {}
// X86: define dso_local x86_regcallcc void @__regcall3__hfa2(double %a.0, double %a.1, double %a.2, double %a.3, double %b.0, double %b.1, double %b.2, double %b.3, ptr dead_on_return inreg noundef %0)
// X86: define dso_local x86_regcallcc void @__regcall3__hfa2(double %a.0, double %a.1, double %a.2, double %a.3, double %b.0, double %b.1, double %b.2, double %b.3, ptr inreg noundef dead_on_return %0)
// X64: define dso_local x86_regcallcc void @__regcall3__hfa2(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double noundef %c)
// Ensure that we pass builtin types directly while counting them against the
@ -61,7 +61,7 @@ void __regcall hfa3(double a, double b, double c, double d, double e, struct HFA
// handling to ensure alignment.
void __regcall hfa4(struct HFA5 a) {}
// X32: define dso_local x86_regcallcc void @__regcall3__hfa4(ptr noundef byval(%struct.HFA5) align 4 %{{.*}})
// Win64: define dso_local x86_regcallcc void @__regcall3__hfa4(ptr dead_on_return noundef %a)
// Win64: define dso_local x86_regcallcc void @__regcall3__hfa4(ptr noundef dead_on_return %a)
// Lin64: define dso_local x86_regcallcc void @__regcall3__hfa4(double %a.coerce0, double %a.coerce1, double %a.coerce2, double %a.coerce3, double %a.coerce4)
// Return HFAs of 4 or fewer elements in registers.
@ -79,7 +79,7 @@ void __regcall hva1(int a, struct HVA4 b, int c) {}
// X64: define dso_local x86_regcallcc void @__regcall3__hva1(i32 noundef %a, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 noundef %c)
void __regcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {}
// X86: define dso_local x86_regcallcc void @__regcall3__hva2(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr dead_on_return inreg noundef %0)
// X86: define dso_local x86_regcallcc void @__regcall3__hva2(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr inreg noundef dead_on_return %0)
// X64: define dso_local x86_regcallcc void @__regcall3__hva2(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> noundef %c)
void __regcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {}
@ -95,6 +95,6 @@ void __regcall odd_size_hva(struct OddSizeHVA a) {}
struct HFA6 { __m128 f[4]; };
struct HFA6 __regcall ret_reg_reused(struct HFA6 a, struct HFA6 b, struct HFA6 c, struct HFA6 d){ struct HFA6 h; return h;}
// X86: define dso_local x86_regcallcc %struct.HFA6 @__regcall3__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr dead_on_return inreg noundef %c, ptr dead_on_return inreg noundef %d)
// X86: define dso_local x86_regcallcc %struct.HFA6 @__regcall3__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr inreg noundef dead_on_return %c, ptr inreg noundef dead_on_return %d)
// Win64: define dso_local x86_regcallcc %struct.HFA6 @__regcall3__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, <4 x float> %c.0, <4 x float> %c.1, <4 x float> %c.2, <4 x float> %c.3, <4 x float> %d.0, <4 x float> %d.1, <4 x float> %d.2, <4 x float> %d.3)
// Lin64: define dso_local x86_regcallcc %struct.HFA6 @__regcall3__ret_reg_reused([4 x <4 x float>] %a.coerce, [4 x <4 x float>] %b.coerce, [4 x <4 x float>] %c.coerce, [4 x <4 x float>] %d.coerce)

View file

@ -19,10 +19,7 @@ double __regcall bar(__sVector a) {
}
// FIXME: Do we need to change for Windows?
// Win: define dso_local x86_regcallcc void @__regcall3__foo(ptr dead_on_unwind noalias writable sret(%struct.__sVector) align 64 %agg.result, i32 noundef %a) #0
// Win: define dso_local x86_regcallcc double @__regcall3__bar(ptr dead_on_return noundef %a) #0
// Win: attributes #0 = { noinline nounwind optnone "min-legal-vector-width"="0" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+avx,+avx2,+avx512f,+avx512vl,+crc32,+cx8,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
// Lin: define dso_local x86_regcallcc %struct.__sVector @__regcall3__foo(i32 noundef %a) #0
// Lin: define dso_local x86_regcallcc double @__regcall3__bar([4 x <8 x double>] %a.coerce0, [4 x <16 x float>] %a.coerce1) #0
// Lin: attributes #0 = { noinline nounwind optnone "min-legal-vector-width"="512" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+avx,+avx2,+avx512f,+avx512vl,+crc32,+cx8,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
// Lin: {{.*}}
// Win: {{.*}}

View file

@ -28,7 +28,7 @@ struct Large { int a[5]; };
void __regcall v4(int a, struct Large b, int c) {}
// Win32: define dso_local x86_regcallcc void @__regcall4__v4(i32 inreg noundef %a, ptr noundef byval(%struct.Large) align 4 %b, i32 inreg noundef %c)
// Lin32: define dso_local x86_regcallcc void @__regcall4__v4(i32 inreg noundef %a, ptr noundef byval(%struct.Large) align 4 %b, i32 noundef %c)
// Win64: define dso_local x86_regcallcc void @__regcall4__v4(i32 noundef %a, ptr dead_on_return noundef %b, i32 noundef %c)
// Win64: define dso_local x86_regcallcc void @__regcall4__v4(i32 noundef %a, ptr noundef dead_on_return %b, i32 noundef %c)
// Lin64: define dso_local x86_regcallcc void @__regcall4__v4(i32 noundef %a, [5 x i32] %b.coerce, i32 noundef %c)
void __regcall v5(long long a, int b, int c) {}
@ -47,7 +47,7 @@ void __regcall hfa1(int a, struct HFA4 b, int c) {}
// indirectly. Additional vector arguments can consume the rest of the SSE
// registers.
void __regcall hfa2(struct HFA4 a, struct HFA4 b, double c) {}
// X86: define dso_local x86_regcallcc void @__regcall4__hfa2(double %a.0, double %a.1, double %a.2, double %a.3, double %b.0, double %b.1, double %b.2, double %b.3, ptr dead_on_return inreg noundef %0)
// X86: define dso_local x86_regcallcc void @__regcall4__hfa2(double %a.0, double %a.1, double %a.2, double %a.3, double %b.0, double %b.1, double %b.2, double %b.3, ptr inreg noundef dead_on_return %0)
// X64: define dso_local x86_regcallcc void @__regcall4__hfa2(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double noundef %c)
// Ensure that we pass builtin types directly while counting them against the
@ -61,7 +61,7 @@ void __regcall hfa3(double a, double b, double c, double d, double e, struct HFA
// handling to ensure alignment.
void __regcall hfa4(struct HFA5 a) {}
// X32: define dso_local x86_regcallcc void @__regcall4__hfa4(ptr noundef byval(%struct.HFA5) align 4 %{{.*}})
// Win64: define dso_local x86_regcallcc void @__regcall4__hfa4(ptr dead_on_return noundef %a)
// Win64: define dso_local x86_regcallcc void @__regcall4__hfa4(ptr noundef dead_on_return %a)
// Lin64: define dso_local x86_regcallcc void @__regcall4__hfa4(double %a.coerce0, double %a.coerce1, double %a.coerce2, double %a.coerce3, double %a.coerce4)
// Return HFAs of 4 or fewer elements in registers.
@ -79,7 +79,7 @@ void __regcall hva1(int a, struct HVA4 b, int c) {}
// X64: define dso_local x86_regcallcc void @__regcall4__hva1(i32 noundef %a, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 noundef %c)
void __regcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {}
// X86: define dso_local x86_regcallcc void @__regcall4__hva2(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr dead_on_return inreg noundef %0)
// X86: define dso_local x86_regcallcc void @__regcall4__hva2(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr inreg noundef dead_on_return %0)
// X64: define dso_local x86_regcallcc void @__regcall4__hva2(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> noundef %c)
void __regcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {}
@ -95,6 +95,6 @@ void __regcall odd_size_hva(struct OddSizeHVA a) {}
struct HFA6 { __m128 f[4]; };
struct HFA6 __regcall ret_reg_reused(struct HFA6 a, struct HFA6 b, struct HFA6 c, struct HFA6 d){ struct HFA6 h; return h;}
// X86: define dso_local x86_regcallcc %struct.HFA6 @__regcall4__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr dead_on_return inreg noundef %c, ptr dead_on_return inreg noundef %d)
// X86: define dso_local x86_regcallcc %struct.HFA6 @__regcall4__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, ptr inreg noundef dead_on_return %c, ptr inreg noundef dead_on_return %d)
// Win64: define dso_local x86_regcallcc %struct.HFA6 @__regcall4__ret_reg_reused(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, <4 x float> %c.0, <4 x float> %c.1, <4 x float> %c.2, <4 x float> %c.3, <4 x float> %d.0, <4 x float> %d.1, <4 x float> %d.2, <4 x float> %d.3)
// Lin64: define dso_local x86_regcallcc %struct.HFA6 @__regcall4__ret_reg_reused([4 x <4 x float>] %a.coerce, [4 x <4 x float>] %b.coerce, [4 x <4 x float>] %c.coerce, [4 x <4 x float>] %d.coerce)

View file

@ -17,7 +17,7 @@ void __vectorcall v3(int a, struct Small b, int c) {}
struct Large { int a[5]; };
void __vectorcall v4(int a, struct Large b, int c) {}
// X86: define dso_local x86_vectorcallcc void @"\01v4@@28"(i32 inreg noundef %a, ptr noundef byval(%struct.Large) align 4 %b, i32 inreg noundef %c)
// X64: define dso_local x86_vectorcallcc void @"\01v4@@40"(i32 noundef %a, ptr dead_on_return noundef %b, i32 noundef %c)
// X64: define dso_local x86_vectorcallcc void @"\01v4@@40"(i32 noundef %a, ptr noundef dead_on_return %b, i32 noundef %c)
void __vectorcall v5(long long a, int b, int c) {}
// X86: define dso_local x86_vectorcallcc void @"\01v5@@16"(i64 noundef %a, i32 inreg noundef %b, i32 inreg noundef %c)
@ -35,21 +35,21 @@ void __vectorcall hfa1(int a, struct HFA4 b, int c) {}
// indirectly. Additional vector arguments can consume the rest of the SSE
// registers.
void __vectorcall hfa2(struct HFA4 a, struct HFA4 b, double c) {}
// X86: define dso_local x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, ptr dead_on_return inreg noundef %b, double inreg noundef %c)
// X64: define dso_local x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, ptr dead_on_return noundef %b, double noundef %c)
// X86: define dso_local x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, ptr inreg noundef dead_on_return %b, double inreg noundef %c)
// X64: define dso_local x86_vectorcallcc void @"\01hfa2@@72"(%struct.HFA4 inreg %a.coerce, ptr noundef dead_on_return %b, double noundef %c)
// Ensure that we pass builtin types directly while counting them against the
// SSE register usage.
void __vectorcall hfa3(double a, double b, double c, double d, double e, struct HFA2 f) {}
// X86: define dso_local x86_vectorcallcc void @"\01hfa3@@56"(double inreg noundef %a, double inreg noundef %b, double inreg noundef %c, double inreg noundef %d, double inreg noundef %e, ptr dead_on_return inreg noundef %f)
// X64: define dso_local x86_vectorcallcc void @"\01hfa3@@56"(double noundef %a, double noundef %b, double noundef %c, double noundef %d, double noundef %e, ptr dead_on_return noundef %f)
// X86: define dso_local x86_vectorcallcc void @"\01hfa3@@56"(double inreg noundef %a, double inreg noundef %b, double inreg noundef %c, double inreg noundef %d, double inreg noundef %e, ptr inreg noundef dead_on_return %f)
// X64: define dso_local x86_vectorcallcc void @"\01hfa3@@56"(double noundef %a, double noundef %b, double noundef %c, double noundef %d, double noundef %e, ptr noundef dead_on_return %f)
// Aggregates with more than four elements are not HFAs and are passed byval.
// Because they are not classified as homogeneous, they don't get special
// handling to ensure alignment.
void __vectorcall hfa4(struct HFA5 a) {}
// X86: define dso_local x86_vectorcallcc void @"\01hfa4@@40"(ptr noundef byval(%struct.HFA5) align 4 %0)
// X64: define dso_local x86_vectorcallcc void @"\01hfa4@@40"(ptr dead_on_return noundef %a)
// X64: define dso_local x86_vectorcallcc void @"\01hfa4@@40"(ptr noundef dead_on_return %a)
// Return HFAs of 4 or fewer elements in registers.
static struct HFA2 g_hfa2;
@ -68,26 +68,26 @@ v4f32 __vectorcall hva1(int a, struct HVA4 b, int c) {return b.w;}
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva1@@80"(i32 noundef %a, %struct.HVA4 inreg %b.coerce, i32 noundef %c)
v4f32 __vectorcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {return c;}
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return inreg noundef %b, <4 x float> inreg noundef %c)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return noundef %b, <4 x float> noundef %c)
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, ptr inreg noundef dead_on_return %b, <4 x float> inreg noundef %c)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva2@@144"(%struct.HVA4 inreg %a.coerce, ptr noundef dead_on_return %b, <4 x float> noundef %c)
v4f32 __vectorcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {return f.x;}
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> inreg noundef %a, <4 x float> inreg noundef %b, <4 x float> inreg noundef %c, <4 x float> inreg noundef %d, <4 x float> inreg noundef %e, ptr dead_on_return inreg noundef %f)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c, <4 x float> noundef %d, <4 x float> noundef %e, ptr dead_on_return noundef %f)
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> inreg noundef %a, <4 x float> inreg noundef %b, <4 x float> inreg noundef %c, <4 x float> inreg noundef %d, <4 x float> inreg noundef %e, ptr inreg noundef dead_on_return %f)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva3@@112"(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c, <4 x float> noundef %d, <4 x float> noundef %e, ptr noundef dead_on_return %f)
// vector types have higher priority then HVA structures, So vector types are allocated first
// and HVAs are allocated if enough registers are available
v4f32 __vectorcall hva4(struct HVA4 a, struct HVA2 b, v4f32 c) {return b.y;}
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return inreg noundef %b, <4 x float> inreg noundef %c)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return noundef %b, <4 x float> noundef %c)
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, ptr inreg noundef dead_on_return %b, <4 x float> inreg noundef %c)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva4@@112"(%struct.HVA4 inreg %a.coerce, ptr noundef dead_on_return %b, <4 x float> noundef %c)
v4f32 __vectorcall hva5(struct HVA3 a, struct HVA3 b, v4f32 c, struct HVA2 d) {return d.y;}
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, ptr dead_on_return inreg noundef %b, <4 x float> inreg noundef %c, %struct.HVA2 inreg %d.coerce)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, ptr dead_on_return noundef %b, <4 x float> noundef %c, %struct.HVA2 inreg %d.coerce)
// X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, ptr inreg noundef dead_on_return %b, <4 x float> inreg noundef %c, %struct.HVA2 inreg %d.coerce)
// X64: define dso_local x86_vectorcallcc <4 x float> @"\01hva5@@144"(%struct.HVA3 inreg %a.coerce, ptr noundef dead_on_return %b, <4 x float> noundef %c, %struct.HVA2 inreg %d.coerce)
struct HVA4 __vectorcall hva6(struct HVA4 a, struct HVA4 b) { return b;}
// X86: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return inreg noundef %b)
// X64: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr dead_on_return noundef %b)
// X86: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr inreg noundef dead_on_return %b)
// X64: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr noundef dead_on_return %b)
struct HVA5 __vectorcall hva7(void) {struct HVA5 a = {}; return a;}
// X86: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind noalias writable sret(%struct.HVA5) align 16 %agg.result)
@ -108,8 +108,8 @@ void __vectorcall odd_size_hva(struct OddSizeHVA a) {}
// consider 'p7' as a register. Instead p5 gets put into the register on the second pass.
// x86 should pass p2, p6 and p7 in registers, then p1 in the second pass.
struct HFA2 __vectorcall AddParticles(struct HFA2 p1, float p2, struct HFA4 p3, int p4, struct HFA2 p5, float p6, float p7, int p8){ return p1;}
// X86: define dso_local x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@84"(%struct.HFA2 inreg %p1.coerce, float inreg noundef %p2, ptr dead_on_return inreg noundef %p3, i32 inreg noundef %p4, ptr dead_on_return noundef %p5, float inreg noundef %p6, float inreg noundef %p7, i32 noundef %p8)
// X64: define dso_local x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@104"(%struct.HFA2 inreg %p1.coerce, float noundef %p2, ptr dead_on_return noundef %p3, i32 noundef %p4, %struct.HFA2 inreg %p5.coerce, float noundef %p6, float noundef %p7, i32 noundef %p8)
// X86: define dso_local x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@84"(%struct.HFA2 inreg %p1.coerce, float inreg noundef %p2, ptr inreg noundef dead_on_return %p3, i32 inreg noundef %p4, ptr noundef dead_on_return %p5, float inreg noundef %p6, float inreg noundef %p7, i32 noundef %p8)
// X64: define dso_local x86_vectorcallcc %struct.HFA2 @"\01AddParticles@@104"(%struct.HFA2 inreg %p1.coerce, float noundef %p2, ptr noundef dead_on_return %p3, i32 noundef %p4, %struct.HFA2 inreg %p5.coerce, float noundef %p6, float noundef %p7, i32 noundef %p8)
// Vectorcall in both architectures allows passing of an HVA as long as there is room,
// even if it is not one of the first 6 arguments. First pass puts p4 into a
@ -117,8 +117,8 @@ struct HFA2 __vectorcall AddParticles(struct HFA2 p1, float p2, struct HFA4 p3,
// in a register, does NOT put p7 in a register (since there's no room), then puts
// p8 in a register.
void __vectorcall HVAAnywhere(struct HFA2 p1, int p2, int p3, float p4, int p5, int p6, struct HFA4 p7, struct HFA2 p8, float p9){}
// X86: define dso_local x86_vectorcallcc void @"\01HVAAnywhere@@88"(%struct.HFA2 inreg %p1.coerce, i32 inreg noundef %p2, i32 inreg noundef %p3, float inreg noundef %p4, i32 noundef %p5, i32 noundef %p6, ptr dead_on_return noundef %p7, %struct.HFA2 inreg %p8.coerce, float inreg noundef %p9)
// X64: define dso_local x86_vectorcallcc void @"\01HVAAnywhere@@112"(%struct.HFA2 inreg %p1.coerce, i32 noundef %p2, i32 noundef %p3, float noundef %p4, i32 noundef %p5, i32 noundef %p6, ptr dead_on_return noundef %p7, %struct.HFA2 inreg %p8.coerce, float noundef %p9)
// X86: define dso_local x86_vectorcallcc void @"\01HVAAnywhere@@88"(%struct.HFA2 inreg %p1.coerce, i32 inreg noundef %p2, i32 inreg noundef %p3, float inreg noundef %p4, i32 noundef %p5, i32 noundef %p6, ptr noundef dead_on_return %p7, %struct.HFA2 inreg %p8.coerce, float inreg noundef %p9)
// X64: define dso_local x86_vectorcallcc void @"\01HVAAnywhere@@112"(%struct.HFA2 inreg %p1.coerce, i32 noundef %p2, i32 noundef %p3, float noundef %p4, i32 noundef %p5, i32 noundef %p6, ptr noundef dead_on_return %p7, %struct.HFA2 inreg %p8.coerce, float noundef %p9)
#ifndef __x86_64__
// This covers the three ways XMM values can be passed on 32-bit x86:
@ -137,9 +137,9 @@ void __vectorcall vectorcall_indirect_vec(
// X86-SAME: double inreg noundef %xmm3,
// X86-SAME: double inreg noundef %xmm4,
// X86-SAME: <4 x float> inreg noundef %xmm5,
// X86-SAME: ptr dead_on_return inreg noundef %0,
// X86-SAME: ptr inreg noundef dead_on_return %0,
// X86-SAME: i32 inreg noundef %edx,
// X86-SAME: ptr dead_on_return noundef %1)
// X86-SAME: ptr noundef dead_on_return %1)
void __vectorcall vectorcall_indirect_fp(
double xmm0, double xmm1, double xmm2, double xmm3, double xmm4,
@ -153,7 +153,7 @@ void __vectorcall vectorcall_indirect_fp(
// X86-SAME: double inreg noundef %xmm3,
// X86-SAME: double inreg noundef %xmm4,
// X86-SAME: <4 x float> inreg noundef %xmm5,
// X86-SAME: ptr dead_on_return inreg noundef %0,
// X86-SAME: ptr inreg noundef dead_on_return %0,
// X86-SAME: i32 inreg noundef %edx,
// X86-SAME: double noundef %mem)
#endif

View file

@ -6,7 +6,7 @@ __float128 fp128_ret(void) { return 0; }
// CHECK-GNU64: define dso_local <2 x i64> @fp128_ret()
__float128 fp128_args(__float128 a, __float128 b) { return a * b; }
// CHECK-GNU64: define dso_local <2 x i64> @fp128_args(ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// CHECK-GNU64: define dso_local <2 x i64> @fp128_args(ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
void fp128_vararg(int a, ...) {
// CHECK-GNU64-LABEL: define dso_local void @fp128_vararg

View file

@ -12,8 +12,8 @@ int128_t foo(void) { return 0; }
int128_t bar(int128_t a, int128_t b) { return a * b; }
// GNU64: define dso_local <2 x i64> @bar(ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// MSC64: define dso_local <2 x i64> @bar(ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// GNU64: define dso_local <2 x i64> @bar(ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
// MSC64: define dso_local <2 x i64> @bar(ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
void vararg(int a, ...) {
// GNU64-LABEL: define{{.*}} void @vararg

View file

@ -219,7 +219,7 @@ TEST(struct_big_1)
// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} dead_on_unwind noalias writable sret
// Should not be byval.
// CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr dead_on_return noundef{{( %.*)?}})
// CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr noundef dead_on_return{{( %.*)?}})
/*****************************************************************************/
/********************************* TYPE MERGING ******************************/

View file

@ -576,7 +576,7 @@ void f(__clang_svmfloat8x4_t, __clang_svmfloat8x4_t);
// CHECK-NEXT: [[COERCE74_EXTRACT2:%.*]] = extractvalue { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } [[COERCE74_TUPLE]], 2
// CHECK-NEXT: [[COERCE74_EXTRACT3:%.*]] = extractvalue { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } [[COERCE74_TUPLE]], 3
// CHECK-NEXT: store { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } zeroinitializer, ptr [[BYVAL_TEMP]], align 2
// CHECK-NEXT: call void @_Z1f10svboolx4_tS_(<vscale x 16 x i1> [[COERCE74_EXTRACT0]], <vscale x 16 x i1> [[COERCE74_EXTRACT1]], <vscale x 16 x i1> [[COERCE74_EXTRACT2]], <vscale x 16 x i1> [[COERCE74_EXTRACT3]], ptr dead_on_return noundef [[BYVAL_TEMP]])
// CHECK-NEXT: call void @_Z1f10svboolx4_tS_(<vscale x 16 x i1> [[COERCE74_EXTRACT0]], <vscale x 16 x i1> [[COERCE74_EXTRACT1]], <vscale x 16 x i1> [[COERCE74_EXTRACT2]], <vscale x 16 x i1> [[COERCE74_EXTRACT3]], ptr noundef dead_on_return [[BYVAL_TEMP]])
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } zeroinitializer, ptr [[COERCE75]], align 16
// CHECK-NEXT: [[COERCE75_TUPLE:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[COERCE75]], align 16
// CHECK-NEXT: [[COERCE75_EXTRACT0:%.*]] = extractvalue { <vscale x 16 x i8>, <vscale x 16 x i8> } [[COERCE75_TUPLE]], 0
@ -1125,7 +1125,7 @@ void f(__clang_svmfloat8x4_t, __clang_svmfloat8x4_t);
// COMPAT_17-NEXT: [[COERCE74_EXTRACT2:%.*]] = extractvalue { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } [[COERCE74_TUPLE]], 2
// COMPAT_17-NEXT: [[COERCE74_EXTRACT3:%.*]] = extractvalue { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } [[COERCE74_TUPLE]], 3
// COMPAT_17-NEXT: store { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } zeroinitializer, ptr [[BYVAL_TEMP]], align 2
// COMPAT_17-NEXT: call void @_Z1f10svboolx4_t10svboolx4_t(<vscale x 16 x i1> [[COERCE74_EXTRACT0]], <vscale x 16 x i1> [[COERCE74_EXTRACT1]], <vscale x 16 x i1> [[COERCE74_EXTRACT2]], <vscale x 16 x i1> [[COERCE74_EXTRACT3]], ptr dead_on_return noundef [[BYVAL_TEMP]])
// COMPAT_17-NEXT: call void @_Z1f10svboolx4_t10svboolx4_t(<vscale x 16 x i1> [[COERCE74_EXTRACT0]], <vscale x 16 x i1> [[COERCE74_EXTRACT1]], <vscale x 16 x i1> [[COERCE74_EXTRACT2]], <vscale x 16 x i1> [[COERCE74_EXTRACT3]], ptr noundef dead_on_return [[BYVAL_TEMP]])
// COMPAT_17-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } zeroinitializer, ptr [[COERCE75]], align 16
// COMPAT_17-NEXT: [[COERCE75_TUPLE:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[COERCE75]], align 16
// COMPAT_17-NEXT: [[COERCE75_EXTRACT0:%.*]] = extractvalue { <vscale x 16 x i8>, <vscale x 16 x i8> } [[COERCE75_TUPLE]], 0

View file

@ -17,4 +17,4 @@ void baz() {
}
// CHECK: declare void @_Z3fooPv(ptr dead_on_unwind writable sret(%class.SMLoc) align 4, ptr noundef)
// CHECK: declare void @_Z3zed5SMLoc(ptr dead_on_return noundef)
// CHECK: declare void @_Z3zed5SMLoc(ptr noundef dead_on_return)

View file

@ -55,18 +55,18 @@ void usage() {
// WINDOWS-NEXT: ret i32 %[[RET]]
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z"(ptr dead_on_return noundef %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z"(ptr noundef dead_on_return %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds nuw %struct.Foo, ptr %[[O]], i32 0, i32 0
// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, ptr %[[X]]
// WINDOWS64: ret i32 %[[LOAD]]
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(ptr dead_on_return noundef %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(ptr noundef dead_on_return %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds nuw %struct.Foo, ptr %[[O]], i32 0, i32 0
// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, ptr %[[X]]
// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1
// WINDOWS64: ret i32 %[[ADD]]
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(ptr dead_on_return noundef %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: define dso_local noundef i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(ptr noundef dead_on_return %[[O:[0-9a-zA-Z]+]])
// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds nuw %struct.Foo, ptr %[[O]], i32 0, i32 0
// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, ptr %[[X]]
// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2
@ -75,7 +75,7 @@ void usage() {
// WINDOWS64: define dso_local void @"?usage@@YAXXZ"()
// WINDOWS64: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo
// WINDOWS64: %[[ARG:[0-9a-zA-Z.]+]] = alloca %struct.Foo
// WINDOWS64: %[[CALL:[0-9a-zA-Z]+]] = call noundef i32 @"?bar@@YAHUFoo@@@Z.resolver"(ptr dead_on_return noundef %[[ARG]])
// WINDOWS64: %[[CALL:[0-9a-zA-Z]+]] = call noundef i32 @"?bar@@YAHUFoo@@@Z.resolver"(ptr noundef dead_on_return %[[ARG]])
// WINDOWS64: define weak_odr dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(ptr %0)
// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(ptr %0)

View file

@ -12,7 +12,7 @@ struct Bar {
void f(Foo);
// CHECK-LABEL: define{{.*}} void @_Z1g3Foo(ptr dead_on_return noundef %foo)
// CHECK-LABEL: define{{.*}} void @_Z1g3Foo(ptr noundef dead_on_return %foo)
void g(Foo foo) {
// CHECK: call void @_ZN3BarC1Ev
// CHECK: @_ZNK3BarcvRK3FooEv

View file

@ -13,7 +13,7 @@ struct Empty {
};
bool foo(Empty e) {
// CHECK: @_Z3foo5Empty(ptr dead_on_return noundef %e)
// CHECK: @_Z3foo5Empty(ptr noundef dead_on_return %e)
// CHECK: call {{.*}} @_ZN5Empty5checkEv(ptr {{[^,]*}} %e)
return e.check();
}
@ -21,6 +21,6 @@ bool foo(Empty e) {
void caller(Empty &e) {
// CHECK: @_Z6callerR5Empty(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %e)
// CHECK: call {{.*}} @_ZN5EmptyC1ERKS_(ptr {{[^,]*}} [[NEWTMP:%.*]], ptr
// CHECK: call {{.*}} @_Z3foo5Empty(ptr dead_on_return noundef [[NEWTMP]])
// CHECK: call {{.*}} @_Z3foo5Empty(ptr noundef dead_on_return [[NEWTMP]])
foo(e);
}

View file

@ -15,6 +15,6 @@ struct S1 {
void __attribute__((fastcall)) foo2(S1 a, int b);
void bar2(S1 a, int b) {
// CHECK-LABEL: define{{.*}} void @_Z4bar22S1i
// CHECK: call x86_fastcallcc void @_Z4foo22S1i(ptr dead_on_return inreg %{{.*}}, i32 inreg %
// CHECK: call x86_fastcallcc void @_Z4foo22S1i(ptr inreg dead_on_return %{{.*}}, i32 inreg %
foo2(a, b);
}

View file

@ -41,8 +41,8 @@ struct D5 : I1, I2, I3 {}; // homogeneous aggregate
// PPC: define{{.*}} void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce)
// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce)
// ARM64: define{{.*}} void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr dead_on_return noundef %x)
// X64: define dso_local x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr dead_on_return noundef %x)
// ARM64: define{{.*}} void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr noundef dead_on_return %x)
// X64: define dso_local x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr noundef dead_on_return %x)
D1 CC func_D1(D1 x) { return x; }
// PPC: define{{.*}} [3 x double] @_Z7func_D22D2([3 x double] %x.coerce)
@ -53,7 +53,7 @@ D2 CC func_D2(D2 x) { return x; }
// PPC: define{{.*}} void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce)
// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce)
// ARM64: define{{.*}} void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, ptr dead_on_return noundef %x)
// ARM64: define{{.*}} void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, ptr noundef dead_on_return %x)
D3 CC func_D3(D3 x) { return x; }
// PPC: define{{.*}} [4 x double] @_Z7func_D42D4([4 x double] %x.coerce)
@ -201,7 +201,7 @@ struct NonHFA {
virtual void f1();
};
double foo(NonHFA v) { return v.x + v.y; }
// WOA64: define dso_local noundef double @"?foo@polymorphic@@YANUNonHFA@1@@Z"(ptr dead_on_return noundef %{{.*}})
// WOA64: define dso_local noundef double @"?foo@polymorphic@@YANUNonHFA@1@@Z"(ptr noundef dead_on_return %{{.*}})
}
namespace trivial_copy_assignment {
struct HFA {
@ -221,7 +221,7 @@ struct NonHFA {
NonHFA &operator=(const NonHFA&);
};
double foo(NonHFA v) { return v.x + v.y; }
// WOA64: define dso_local noundef double @"?foo@non_trivial_copy_assignment@@YANUNonHFA@1@@Z"(ptr dead_on_return noundef %{{.*}})
// WOA64: define dso_local noundef double @"?foo@non_trivial_copy_assignment@@YANUNonHFA@1@@Z"(ptr noundef dead_on_return %{{.*}})
}
namespace user_provided_ctor {
struct HFA {
@ -251,7 +251,7 @@ struct NonHFA {
~NonHFA();
};
double foo(NonHFA v) { return v.x + v.y; }
// WOA64: define dso_local noundef double @"?foo@non_trivial_dtor@@YANUNonHFA@1@@Z"(ptr dead_on_return noundef %{{.*}})
// WOA64: define dso_local noundef double @"?foo@non_trivial_dtor@@YANUNonHFA@1@@Z"(ptr noundef dead_on_return %{{.*}})
}
namespace non_empty_base {
struct non_empty_base { double d; };
@ -272,7 +272,7 @@ struct NonHFA {
empty e;
};
double foo(NonHFA v) { return v.x + v.y; }
// WOA64: define dso_local noundef double @"?foo@empty_field@@YANUNonHFA@1@@Z"(ptr dead_on_return noundef %{{.*}})
// WOA64: define dso_local noundef double @"?foo@empty_field@@YANUNonHFA@1@@Z"(ptr noundef dead_on_return %{{.*}})
}
namespace non_empty_field {
struct non_empty { double d; };

View file

@ -22,7 +22,7 @@ void test() {
// CHECK: %[[V:.*]] = getelementptr inbounds nuw <{ %struct.A }>, ptr %[[ARG]], i32 0, i32 0
// CHECK: %call = call x86_thiscallcc noundef i32
// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ@QBE?A?<auto>@@UA@@@Z"
// CHECK-SAME: (ptr noundef %this, ptr dead_on_return noundef %[[V]])
// CHECK-SAME: (ptr noundef %this, ptr noundef dead_on_return %[[V]])
// CHECK: define internal noundef i32
// CHECK-SAME: @"?__invoke@<lambda_0>@?0??test@@YAXXZ@CA?A?<auto>@@UA@@@Z"
@ -31,12 +31,12 @@ void test() {
// CHECK: %[[VAR:.*]] = getelementptr inbounds nuw <{ %struct.A }>, ptr %[[ARG]], i32 0, i32 0
// CHECK: %call = call x86_thiscallcc noundef i32
// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ@QBE?A?<auto>@@UA@@@Z"
// CHECK-SAME: (ptr noundef %unused.capture, ptr dead_on_return noundef %[[VAR]])
// CHECK-SAME: (ptr noundef %unused.capture, ptr noundef dead_on_return %[[VAR]])
// CHECK: ret i32 %call
// CHECK: define internal x86_thiscallcc noundef i32
// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ@QBE?A?<auto>@@UA@@@Z"
// CHECK-SAME: (ptr noundef %this, ptr dead_on_return noundef %[[ARG:.*]])
// CHECK-SAME: (ptr noundef %this, ptr noundef dead_on_return %[[ARG:.*]])
// CHECK: %this.addr = alloca ptr, align 4
// CHECK: store ptr %this, ptr %this.addr, align 4
// CHECK: %this1 = load ptr, ptr %this.addr, align 4

View file

@ -57,7 +57,7 @@ int receive_both(Both o) {
}
// CHECK-LABEL: define dso_local noundef i32 @"?receive_both@@Y{{.*}}"
// CHECK-SAME: (ptr dead_on_return noundef %o)
// CHECK-SAME: (ptr noundef dead_on_return %o)
int pass_both() {
gvi32 = receive_both(Both());
@ -67,7 +67,7 @@ int pass_both() {
// CHECK-LABEL: define dso_local noundef i32 @"?pass_both@@Y{{.*}}"
// CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8
// CHECK: call x86_thiscallcc noundef ptr @"??0Both@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])
// CHECK: call noundef i32 @"?receive_both@@Y{{.*}}"(ptr dead_on_return noundef [[TMP]])
// CHECK: call noundef i32 @"?receive_both@@Y{{.*}}"(ptr noundef dead_on_return [[TMP]])
int receive_inalloca_both(NonTrivial nt, Both o) {
return nt.x + o.x + o.y;
@ -101,11 +101,11 @@ struct [[trivial_abi]] alignas(8) MyPtr {
int receiveMyPtr(MyPtr o) { return *o.ptr; }
// CHECK-LABEL: define dso_local noundef i32 @"?receiveMyPtr@@Y{{.*}}"
// CHECK-SAME: (ptr dead_on_return noundef %o)
// CHECK-SAME: (ptr noundef dead_on_return %o)
int passMyPtr() { return receiveMyPtr(MyPtr()); }
// CHECK-LABEL: define dso_local noundef i32 @"?passMyPtr@@Y{{.*}}"
// CHECK: [[TMP:%[^ ]*]] = alloca %struct.MyPtr, align 8
// CHECK: call x86_thiscallcc noundef ptr @"??0MyPtr@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])
// CHECK: call noundef i32 @"?receiveMyPtr@@Y{{.*}}"(ptr dead_on_return noundef [[TMP]])
// CHECK: call noundef i32 @"?receiveMyPtr@@Y{{.*}}"(ptr noundef dead_on_return [[TMP]])

View file

@ -56,7 +56,7 @@ void __fastcall fastcall_receive_vec(__m128 x, __m128 y, __m128 z, __m128 w, int
// CHECK-SAME: (<4 x float> inreg noundef %x,
// CHECK-SAME: <4 x float> inreg noundef %y,
// CHECK-SAME: <4 x float> inreg noundef %z,
// CHECK-SAME: ptr dead_on_return inreg noundef %0,
// CHECK-SAME: ptr inreg noundef dead_on_return %0,
// CHECK-SAME: i32 inreg noundef %edx,
// CHECK-SAME: ptr inalloca(<{ ptr, %struct.NonTrivial }>) %1)
@ -73,6 +73,6 @@ void __vectorcall vectorcall_receive_vec(double xmm0, double xmm1, double xmm2,
// CHECK-SAME: <4 x float> inreg noundef %x,
// CHECK-SAME: <4 x float> inreg noundef %y,
// CHECK-SAME: <4 x float> inreg noundef %z,
// CHECK-SAME: ptr dead_on_return inreg noundef %0,
// CHECK-SAME: ptr inreg noundef dead_on_return %0,
// CHECK-SAME: i32 inreg noundef %edx,
// CHECK-SAME: ptr inalloca(<{ ptr, %struct.NonTrivial }>) %1)

View file

@ -16,7 +16,7 @@ int f(A* a, int (A::*fp)()) {
// CHECK-NOT: }
// CHECK: ret i32 1
// MINGW64-LABEL: define dso_local noundef i32 @_Z2g1v()
// MINGW64: call noundef i32 @_Z1fP1AMS_FivE(ptr noundef %{{.*}}, ptr dead_on_return noundef %{{.*}})
// MINGW64: call noundef i32 @_Z1fP1AMS_FivE(ptr noundef %{{.*}}, ptr noundef dead_on_return %{{.*}})
int g1() {
A a;
return f(&a, &A::vf1);
@ -26,7 +26,7 @@ int g1() {
// CHECK-NOT: }
// CHECK: ret i32 2
// MINGW64-LABEL: define dso_local noundef i32 @_Z2g2v()
// MINGW64: call noundef i32 @_Z1fP1AMS_FivE(ptr noundef %{{.*}}, ptr dead_on_return noundef %{{.*}})
// MINGW64: call noundef i32 @_Z1fP1AMS_FivE(ptr noundef %{{.*}}, ptr noundef dead_on_return %{{.*}})
int g2() {
A a;
return f(&a, &A::vf2);

View file

@ -24,7 +24,7 @@ void foo(A a, A b, A c) {
// X86: ret void
// X64-LABEL: define dso_local void @"?foo@@YAXUA@@00@Z"
// X64: (ptr dead_on_return noundef %[[a:[^,]*]], ptr dead_on_return noundef %[[b:[^,]*]], ptr dead_on_return noundef %[[c:[^)]*]])
// X64: (ptr noundef dead_on_return %[[a:[^,]*]], ptr noundef dead_on_return %[[b:[^,]*]], ptr noundef dead_on_return %[[c:[^)]*]])
// X64: call void @"??1A@@QEAA@XZ"(ptr {{[^,]*}} %[[a]])
// X64: call void @"??1A@@QEAA@XZ"(ptr {{[^,]*}} %[[b]])
// X64: call void @"??1A@@QEAA@XZ"(ptr {{[^,]*}} %[[c]])
@ -64,7 +64,7 @@ void call_foo() {
// X64: invoke noundef ptr @"??0A@@QEAA@H@Z"(ptr {{[^,]*}} %[[arg2:[^,]*]], i32 noundef 2)
// X64: invoke noundef ptr @"??0A@@QEAA@H@Z"(ptr {{[^,]*}} %[[arg1:[^,]*]], i32 noundef 1)
// X64: call void @"?foo@@YAXUA@@00@Z"
// X64: (ptr dead_on_return noundef %[[arg1]], ptr dead_on_return noundef %[[arg2]], ptr dead_on_return noundef %[[arg3]])
// X64: (ptr noundef dead_on_return %[[arg1]], ptr noundef dead_on_return %[[arg2]], ptr noundef dead_on_return %[[arg3]])
// X64: ret void
//
// lpad2:

View file

@ -22,10 +22,10 @@ C::C() {} // force emission
// CHECK32-NEXT: ret void
// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z"
// CHECK64: (ptr noundef %this, ptr dead_on_return noundef %x)
// CHECK64: (ptr noundef %this, ptr noundef dead_on_return %x)
// CHECK64: getelementptr i8, ptr %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@byval_thunk@@UEAAXUAgg@2@@Z"
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr dead_on_return noundef %x)
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr noundef dead_on_return %x)
// CHECK64-NOT: call
// CHECK64: ret void
}
@ -54,10 +54,10 @@ C::C() {} // force emission
// CHECK32-NEXT: ret void
// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z"
// CHECK64: (ptr noundef %this, ptr dead_on_return noundef %x)
// CHECK64: (ptr noundef %this, ptr noundef dead_on_return %x)
// CHECK64: getelementptr i8, ptr %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@stdcall_thunk@@UEAAXUAgg@2@@Z"
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr dead_on_return noundef %x)
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr noundef dead_on_return %x)
// CHECK64-NOT: call
// CHECK64: ret void
}
@ -86,10 +86,10 @@ C::C() {} // force emission
// CHECK32-NEXT: ret ptr %[[rv]]
// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z"
// CHECK64: (ptr noundef %this, ptr dead_on_unwind noalias writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr dead_on_return noundef %x)
// CHECK64: (ptr noundef %this, ptr dead_on_unwind noalias writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef dead_on_return %x)
// CHECK64: getelementptr i8, ptr %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@sret_thunk@@UEAA?AUAgg@2@U32@@Z"
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr dead_on_unwind writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr dead_on_return noundef %x)
// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr dead_on_unwind writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef dead_on_return %x)
// CHECK64-NOT: call
// CHECK64: ret void
}

View file

@ -428,7 +428,7 @@ bool nullTestDataUnspecified(int Unspecified::*mp) {
// Pass this large type indirectly.
// X64-LABEL: define dso_local noundef zeroext i1 @"?nullTestDataUnspecified@@
// X64: (ptr dead_on_return noundef %0)
// X64: (ptr noundef dead_on_return %0)
}
bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
@ -590,7 +590,7 @@ bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
// CHECK: }
// X64-LABEL: define dso_local noundef zeroext i1 @"?unspecFuncMemptrEq@@
// X64: (ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// X64: (ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
}
bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
@ -635,7 +635,7 @@ bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) {
// CHECK: }
// X64-LABEL: define dso_local noundef zeroext i1 @"?unspecDataMemptrEq@@
// X64: (ptr dead_on_return noundef %0, ptr dead_on_return noundef %1)
// X64: (ptr noundef dead_on_return %0, ptr noundef dead_on_return %1)
}
void (Multiple::*convertB2FuncToMultiple(void (B2::*mp)()))() {

View file

@ -175,7 +175,7 @@ void multibyte_arg(Multibyte s) {}
void packed_arg(Packed s) {}
// LINUX-LABEL: define{{.*}} void @_Z10packed_arg6Packed(ptr noundef byval(%struct.Packed) align 4 %s)
// WIN32: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(ptr noundef byval(%struct.Packed) align 4 %s)
// WIN64: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(ptr dead_on_return noundef %s)
// WIN64: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(ptr noundef dead_on_return %s)
// Test that dtors are invoked in the callee.
void small_arg_with_dtor(SmallWithDtor s) {}
@ -190,7 +190,7 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WOA64: }
// FIXME: MSVC incompatible!
// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(ptr dead_on_return noundef %s) {{.*}} {
// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(ptr noundef dead_on_return %s) {{.*}} {
// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA@XZ"(ptr {{[^,]*}} %s)
// WOA: }
@ -220,7 +220,7 @@ void ref_small_arg_with_dtor(const SmallWithDtor &s) { }
// WIN64-LABEL: define dso_local void @"?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %s)
void big_arg_with_dtor(BigWithDtor s) {}
// WIN64-LABEL: define dso_local void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr dead_on_return noundef %s)
// WIN64-LABEL: define dso_local void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr noundef dead_on_return %s)
// WIN64: call void @"??1BigWithDtor@@QEAA@XZ"
// WIN64: }
@ -231,7 +231,7 @@ void call_big_arg_with_dtor() {
// larger than 8 bytes and is passed indirectly.
// WIN64-LABEL: define dso_local void @"?call_big_arg_with_dtor@@YAXXZ"()
// WIN64: call noundef ptr @"??0BigWithDtor@@QEAA@XZ"
// WIN64: call void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr dead_on_return noundef %{{.*}})
// WIN64: call void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(ptr noundef dead_on_return %{{.*}})
// WIN64-NOT: call void @"??1BigWithDtor@@QEAA@XZ"
// WIN64: ret void
@ -259,22 +259,22 @@ void eh_cleanup_arg_with_dtor() {
// WIN32: }
void small_arg_with_vftable(SmallWithVftable s) {}
// LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(ptr dead_on_return noundef %s)
// LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(ptr noundef dead_on_return %s)
// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr inalloca(<{ %struct.SmallWithVftable }>) %0)
// WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr dead_on_return noundef %s)
// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr dead_on_return noundef %s)
// WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr noundef dead_on_return %s)
// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(ptr noundef dead_on_return %s)
void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
// LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(ptr dead_on_return noundef %s)
// LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(ptr noundef dead_on_return %s)
// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr inalloca(<{ %struct.MediumWithCopyCtor }>) %0)
// WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr dead_on_return noundef %s)
// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr dead_on_return noundef %s)
// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr dead_on_return noundef %s)
// WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef dead_on_return %s)
// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef dead_on_return %s)
// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(ptr noundef dead_on_return %s)
void big_arg(Big s) {}
// LINUX-LABEL: define{{.*}} void @_Z7big_arg3Big(ptr noundef byval(%struct.Big) align 4 %s)
// WIN32: define dso_local void @"?big_arg@@YAXUBig@@@Z"(ptr noundef byval(%struct.Big) align 4 %s)
// WIN64: define dso_local void @"?big_arg@@YAXUBig@@@Z"(ptr dead_on_return noundef %s)
// WIN64: define dso_local void @"?big_arg@@YAXUBig@@@Z"(ptr noundef dead_on_return %s)
// PR27607: We would attempt to load i32 value out of the reference instead of
// just loading the pointer from the struct during argument expansion.
@ -346,7 +346,7 @@ class Class {
void thiscall_method_arg(Big s) {}
// LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(ptr {{[^,]*}} %this, ptr noundef byval(%struct.Big) align 4 %s)
// WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUBig@@@Z"(ptr {{[^,]*}} %this, ptr noundef byval(%struct.Big) align 4 %s)
// WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUBig@@@Z"(ptr {{[^,]*}} %this, ptr dead_on_return noundef %s)
// WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUBig@@@Z"(ptr {{[^,]*}} %this, ptr noundef dead_on_return %s)
};
void use_class() {

View file

@ -18,4 +18,4 @@ A B::foo(A x) {
return x;
}
// CHECK-LABEL: define{{.*}} void @"?foo@B@@QEAA?AUA@@U2@@Z"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.A) align 4 %agg.result, ptr dead_on_return noundef %x)
// CHECK-LABEL: define{{.*}} void @"?foo@B@@QEAA?AUA@@U2@@Z"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.A) align 4 %agg.result, ptr noundef dead_on_return %x)

View file

@ -105,7 +105,7 @@ int main(int argc, char **argv) {
// CHECK: [[ARGC:%.+]] = load i32, ptr %
// CHECK: [[P1_X_ARGC_0:%.+]] = call noundef i32 @"?GetX@S@@QEAAHHH@Z"(ptr {{[^,]*}} [[P1]], i32 noundef [[ARGC]], i32 noundef 0)
// CHECK: [[CAST:%.+]] = trunc i32 [[P1_X_ARGC_0]] to i8
// CHECK: [[P2_Y_p1_X_ARGC_0_T:%.+]] = call noundef i8 @"?GetY@?$St@M@@QEAADDVTest1@@@Z"(ptr {{[^,]*}} [[P2_2]], i8 noundef [[CAST]], ptr dead_on_return noundef %{{.+}})
// CHECK: [[P2_Y_p1_X_ARGC_0_T:%.+]] = call noundef i8 @"?GetY@?$St@M@@QEAADDVTest1@@@Z"(ptr {{[^,]*}} [[P2_2]], i8 noundef [[CAST]], ptr noundef dead_on_return %{{.+}})
// CHECK: [[CAST:%.+]] = sitofp i8 [[P2_Y_p1_X_ARGC_0_T]] to float
// CHECK: [[J:%.+]] = load i32, ptr %
// CHECK: [[CAST1:%.+]] = sitofp i32 [[J]] to float
@ -124,6 +124,6 @@ int main(int argc, char **argv) {
// CHECK: call noundef i32 @"?GetX@?$St@H@@QEAAHHH@Z"(ptr {{[^,]*}} [[BAR]], i32 noundef %{{.+}} i32 noundef %{{.+}})
// CHECK: call void @"?PutY@?$St@H@@QEAAXDHN@Z"(ptr {{[^,]*}} [[BAR]], i8 noundef %{{.+}}, i32 noundef %{{.+}}, double noundef %{{.+}}
// CHECK: call noundef i32 @"?GetX@?$St@H@@QEAAHHH@Z"(ptr {{[^,]*}} [[BAR]], i32 noundef %{{.+}} i32 noundef %{{.+}})
// CHECK: call noundef i8 @"?GetY@?$St@H@@QEAADDVTest1@@@Z"(ptr {{[^,]*}} [[BAR]], i8 noundef %{{.+}}, ptr dead_on_return noundef %{{.+}})
// CHECK: call noundef i8 @"?GetY@?$St@H@@QEAADDVTest1@@@Z"(ptr {{[^,]*}} [[BAR]], i8 noundef %{{.+}}, ptr noundef dead_on_return %{{.+}})
// CHECK: call noundef i32 @"?PutX@?$St@H@@QEAAHHHH@Z"(ptr {{[^,]*}} [[BAR]], i32 noundef %{{.+}}, i32 noundef %{{.+}}, i32 noundef %{{.+}})
#endif //HEADER

View file

@ -14,8 +14,8 @@ struct Foo {
// Make sure noalias is added to indirect arguments with trivially copyable types
// if -fpass-by-value-is-noalias is provided.
// WITH_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr dead_on_return noalias noundef %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr dead_on_return noundef %arg)
// WITH_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr noalias noundef dead_on_return %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr noundef dead_on_return %arg)
void take(Foo arg) {}
int G;
@ -38,8 +38,8 @@ struct NonTrivial {
// Make sure noalias is not added to indirect arguments that are not trivially
// copyable even if -fpass-by-value-is-noalias is provided.
// WITH_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr dead_on_return noundef %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr dead_on_return noundef %arg)
// WITH_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr noundef dead_on_return %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr noundef dead_on_return %arg)
void take(NonTrivial arg) {}
// Escape examples. Pointers to the objects passed to take() may escape, depending on whether a temporary copy is created or not (e.g. due to NRVO).
@ -54,8 +54,8 @@ struct A {
};
A *p;
// WITH_NOALIAS: define{{.*}} void @_Z4take1A(ptr dead_on_return noalias noundef %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take1A(ptr dead_on_return noundef %arg)
// WITH_NOALIAS: define{{.*}} void @_Z4take1A(ptr noalias noundef dead_on_return %arg)
// NO_NOALIAS: define{{.*}} void @_Z4take1A(ptr noundef dead_on_return %arg)
void take(A arg) {}
// WITH_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result, ptr noundef %where)

View file

@ -24,7 +24,7 @@ struct __attribute__((trivial_abi)) TrivialSA {
// Check that TrivialSA is passed indirectly despite being annotated with
// 'trivial_abi'.
// CHECK: define {{.*}}void @_Z18testParamTrivialSA9TrivialSA(ptr dead_on_return noundef %{{.*}})
// CHECK: define {{.*}}void @_Z18testParamTrivialSA9TrivialSA(ptr noundef dead_on_return %{{.*}})
void testParamTrivialSA(TrivialSA a) {
}

View file

@ -11,7 +11,7 @@ struct S1 {
};
void __attribute__((regparm(3))) foo2(S1 a, int b);
// CHECK: declare void @_Z4foo22S1i(ptr dead_on_return inreg noundef, i32 inreg noundef)
// CHECK: declare void @_Z4foo22S1i(ptr inreg noundef dead_on_return, i32 inreg noundef)
void bar2(S1 a, int b) {
foo2(a, b);
}

View file

@ -140,7 +140,7 @@ void testIgnoredSmall() {
testReturnSmall();
}
// CHECK: define{{.*}} void @_Z14testParamLarge5Large(ptr dead_on_return noundef %[[A:.*]])
// CHECK: define{{.*}} void @_Z14testParamLarge5Large(ptr noundef dead_on_return %[[A:.*]])
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN5LargeD1Ev(ptr {{[^,]*}} %[[A]])
// CHECK: ret void
// CHECK: }
@ -163,7 +163,7 @@ Large testReturnLarge() {
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE]], align 8
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN5LargeC1Ev(ptr {{[^,]*}} %[[T]])
// CHECK: %[[CALL1:.*]] = call noundef ptr @_ZN5LargeC1ERKS_(ptr {{[^,]*}} %[[AGG_TMP]], ptr noundef nonnull align 8 dereferenceable(520) %[[T]])
// CHECK: call void @_Z14testParamLarge5Large(ptr dead_on_return noundef %[[AGG_TMP]])
// CHECK: call void @_Z14testParamLarge5Large(ptr noundef dead_on_return %[[AGG_TMP]])
// CHECK: %[[CALL2:.*]] = call noundef ptr @_ZN5LargeD1Ev(ptr {{[^,]*}} %[[T]])
// CHECK: ret void
// CHECK: }
@ -176,7 +176,7 @@ void testCallLarge0() {
// CHECK: define{{.*}} void @_Z14testCallLarge1v()
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8
// CHECK: call void @_Z15testReturnLargev(ptr dead_on_unwind writable sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_TMP]])
// CHECK: call void @_Z14testParamLarge5Large(ptr dead_on_return noundef %[[AGG_TMP]])
// CHECK: call void @_Z14testParamLarge5Large(ptr noundef dead_on_return %[[AGG_TMP]])
// CHECK: ret void
// CHECK: }
@ -244,7 +244,7 @@ void testExceptionSmall() {
// CHECK: call noundef ptr @_ZN5LargeC1Ev(ptr {{[^,]*}} %[[AGG_TMP]])
// CHECK: invoke noundef ptr @_ZN5LargeC1Ev(ptr {{[^,]*}} %[[AGG_TMP1]])
// CHECK: call void @_Z20calleeExceptionLarge5LargeS_(ptr dead_on_return noundef %[[AGG_TMP]], ptr dead_on_return noundef %[[AGG_TMP1]])
// CHECK: call void @_Z20calleeExceptionLarge5LargeS_(ptr noundef dead_on_return %[[AGG_TMP]], ptr noundef dead_on_return %[[AGG_TMP1]])
// CHECK-NEXT: ret void
// CHECK: landingpad { ptr, i32 }

View file

@ -59,12 +59,12 @@ void bar() {
// CHECK-LABEL: define{{.*}} void @_ZN9move_ctor3barEv()
// CHECK: call void @_Z{{.*}}C1Ev(
// CHECK-NOT: call
// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(ptr dead_on_return noundef %{{.*}})
// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(ptr noundef dead_on_return %{{.*}})
// OLDABI: call void @_ZN9move_ctor3fooENS_1AE(ptr %{{.*}})
// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr dead_on_return noundef)
// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr noundef dead_on_return)
// OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr)
// WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(ptr dead_on_return noundef)
// WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(ptr noundef dead_on_return)
}
namespace all_deleted {
@ -81,12 +81,12 @@ void bar() {
// CHECK-LABEL: define{{.*}} void @_ZN11all_deleted3barEv()
// CHECK: call void @_Z{{.*}}C1Ev(
// CHECK-NOT: call
// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})
// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(ptr noundef dead_on_return %{{.*}})
// OLDABI: call void @_ZN11all_deleted3fooENS_1AE(ptr %{{.*}})
// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr dead_on_return noundef)
// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr noundef dead_on_return)
// OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr)
// WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)
// WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(ptr noundef dead_on_return)
}
namespace implicitly_deleted {
@ -102,14 +102,14 @@ void bar() {
// CHECK-LABEL: define{{.*}} void @_ZN18implicitly_deleted3barEv()
// CHECK: call void @_Z{{.*}}C1Ev(
// CHECK-NOT: call
// NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})
// NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr noundef dead_on_return %{{.*}})
// OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr %{{.*}})
// NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr dead_on_return noundef)
// NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr noundef dead_on_return)
// OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr)
// In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.
// WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64
// WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)
// WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(ptr noundef dead_on_return)
}
namespace one_deleted {
@ -125,12 +125,12 @@ void bar() {
// CHECK-LABEL: define{{.*}} void @_ZN11one_deleted3barEv()
// CHECK: call void @_Z{{.*}}C1Ev(
// CHECK-NOT: call
// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})
// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(ptr noundef dead_on_return %{{.*}})
// OLDABI: call void @_ZN11one_deleted3fooENS_1AE(ptr %{{.*}})
// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr dead_on_return noundef)
// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr noundef dead_on_return)
// OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr)
// WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)
// WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(ptr noundef dead_on_return)
}
namespace copy_defaulted {
@ -170,7 +170,7 @@ void bar() {
// CHECK: call void @_ZN14move_defaulted3fooENS_1AE(ptr %{{.*}})
// CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(ptr)
// WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(ptr dead_on_return noundef)
// WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(ptr noundef dead_on_return)
}
namespace trivial_defaulted {
@ -207,12 +207,12 @@ void bar() {
}
// CHECK-LABEL: define{{.*}} void @_ZN14two_copy_ctors3barEv()
// CHECK: call void @_Z{{.*}}C1Ev(
// NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr dead_on_return noundef %{{.*}})
// NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef dead_on_return %{{.*}})
// OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval
// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr dead_on_return noundef)
// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef dead_on_return)
// OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval
// WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(ptr dead_on_return noundef)
// WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(ptr noundef dead_on_return)
}
namespace definition_only {

View file

@ -46,14 +46,14 @@ struct copy_ctor {
copy_ctor(copy_ctor const &);
};
test(copy_ctor);
// CHECK: define void @_Z7forward9copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.copy_ctor) align 8 %{{.*}}, ptr dead_on_return nonnull %{{.*}})
// CHECK: define void @_Z7forward9copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.copy_ctor) align 8 %{{.*}}, ptr nonnull dead_on_return %{{.*}})
//
// CHECK: declare ptr @_ZN9copy_ctorC1ERKS_(ptr {{[^,]*}} returned {{[^,]*}}, ptr nonnull align 8 dereferenceable(8))
//
// CHECK: define void @_Z14test_copy_ctorv()
// CHECK: %[[tmp:.*]] = alloca %struct.copy_ctor, align 8
// CHECK: call void @_Z13def_copy_ctorv(ptr dead_on_unwind nonnull writable sret(%struct.copy_ctor) align 8 %[[tmp]])
// CHECK: call void @_Z3use9copy_ctor(ptr dead_on_return nonnull %[[tmp]])
// CHECK: call void @_Z3use9copy_ctor(ptr nonnull dead_on_return %[[tmp]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use9copy_ctor(ptr dead_on_return)
@ -64,14 +64,14 @@ struct __attribute__((aligned(16))) aligned_copy_ctor {
aligned_copy_ctor(aligned_copy_ctor const &);
};
test(aligned_copy_ctor);
// CHECK: define void @_Z7forward17aligned_copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.aligned_copy_ctor) align 16 %{{.*}}, ptr dead_on_return nonnull %{{.*}})
// CHECK: define void @_Z7forward17aligned_copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.aligned_copy_ctor) align 16 %{{.*}}, ptr nonnull dead_on_return %{{.*}})
//
// CHECK: declare ptr @_ZN17aligned_copy_ctorC1ERKS_(ptr {{[^,]*}} returned {{[^,]*}}, ptr nonnull align 16 dereferenceable(16))
//
// CHECK: define void @_Z22test_aligned_copy_ctorv()
// CHECK: %[[tmp:.*]] = alloca %struct.aligned_copy_ctor, align 16
// CHECK: call void @_Z21def_aligned_copy_ctorv(ptr dead_on_unwind nonnull writable sret(%struct.aligned_copy_ctor) align 16 %[[tmp]])
// CHECK: call void @_Z3use17aligned_copy_ctor(ptr dead_on_return nonnull %[[tmp]])
// CHECK: call void @_Z3use17aligned_copy_ctor(ptr nonnull dead_on_return %[[tmp]])
// CHECK: ret void
//
// CHECK: declare void @_Z3use17aligned_copy_ctor(ptr dead_on_return)

View file

@ -18,7 +18,7 @@ struct NonTrivial {
SWIFTCALL int receiveNonTrivial(NonTrivial o) { return o.o; }
// CHECK-LABEL: define dso_local swiftcc noundef i32 @"?receiveNonTrivial@@YSHUNonTrivial@@@Z"(ptr dead_on_return noundef %o)
// CHECK-LABEL: define dso_local swiftcc noundef i32 @"?receiveNonTrivial@@YSHUNonTrivial@@@Z"(ptr noundef dead_on_return %o)
int passNonTrivial() {
return receiveNonTrivial({});
@ -26,4 +26,4 @@ int passNonTrivial() {
// CHECK-LABEL: define dso_local noundef i32 @"?passNonTrivial@@YAHXZ"()
// CHECK-NOT: stacksave
// CHECK: call swiftcc noundef i32 @"?receiveNonTrivial@@YSHUNonTrivial@@@Z"(ptr dead_on_return noundef %{{.*}})
// CHECK: call swiftcc noundef i32 @"?receiveNonTrivial@@YSHUNonTrivial@@@Z"(ptr noundef dead_on_return %{{.*}})

View file

@ -26,9 +26,9 @@ void fb(CustomResource a) {
CustomResource b = a;
}
// CHECK: define hidden void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef %a)
// CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef %{{.*}})
// CHECK: declare hidden void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef)
// CHECK: define hidden void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr noundef dead_on_return %a)
// CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef dead_on_return %{{.*}})
// CHECK: declare hidden void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef dead_on_return)
void foo2(RWBuffer<float4> buf);
void fc(RWBuffer<float4> a) {
@ -44,9 +44,9 @@ struct MyStruct {
int2 i;
};
// CHECK: define hidden void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef %a)
// CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef %{{.*}})
// CHECK: declare hidden void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef)
// CHECK: define hidden void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr noundef dead_on_return %a)
// CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef dead_on_return %{{.*}})
// CHECK: declare hidden void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef dead_on_return)
void foo3(StructuredBuffer<MyStruct> buf);
void fe(StructuredBuffer<MyStruct> a) {

View file

@ -31,7 +31,7 @@ uint Find(Node SortedTree[MAX], uint key) {
}
// CHECK: Function Attrs:{{.*}}norecurse
// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr dead_on_return noundef %encodedTree, i32 noundef %maxDepth) [[Attr:\#[0-9]+]]
// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr noundef dead_on_return %encodedTree, i32 noundef %maxDepth) [[Attr:\#[0-9]+]]
// CHECK: ret i1
// Initialize tree with given buffer
// Imagine the inout works

View file

@ -17,6 +17,6 @@ struct Foo {
Bar *__weak f;
};
// WITH_NOALIAS: define{{.*}} void @take(ptr dead_on_return noundef %arg)
// NO_NOALIAS: define{{.*}} void @take(ptr dead_on_return noundef %arg)
// WITH_NOALIAS: define{{.*}} void @take(ptr noundef dead_on_return %arg)
// NO_NOALIAS: define{{.*}} void @take(ptr noundef dead_on_return %arg)
void take(struct Foo arg) {}

View file

@ -130,7 +130,7 @@ void test_move_assignment_Weak(Weak *p) {
*p = getWeak();
}
// COMMON: define{{.*}} void @test_parameter_Weak(ptr dead_on_return noundef %[[A:.*]])
// COMMON: define{{.*}} void @test_parameter_Weak(ptr noundef dead_on_return %[[A:.*]])
// COMMON: call void @__destructor_{{.*}}(ptr %[[A]])
void test_parameter_Weak(Weak a) {
@ -142,7 +142,7 @@ void test_parameter_Weak(Weak a) {
// COMMON: store ptr %[[A]], ptr %[[A_ADDR]]
// COMMON: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]]
// COMMON: call void @__copy_constructor_{{.*}}(ptr %[[AGG_TMP]], ptr %[[V0]])
// COMMON: call void @calleeWeak(ptr dead_on_return noundef %[[AGG_TMP]])
// COMMON: call void @calleeWeak(ptr noundef dead_on_return %[[AGG_TMP]])
// COMMON-NEXT: ret
void test_argument_Weak(Weak *a) {
@ -164,7 +164,7 @@ Weak test_return_Weak(Weak *a) {
// COMMON: %[[AGG_TMP:.*]] = alloca %[[STRUCT_WEAK]]
// COMMON: br i1
// COMMON: call void @objc_msgSend({{.*}}, ptr dead_on_return noundef %[[AGG_TMP]])
// COMMON: call void @objc_msgSend({{.*}}, ptr noundef dead_on_return %[[AGG_TMP]])
// COMMON: br
// COMMON: call void @__destructor_{{.*}}(ptr %[[AGG_TMP]])

View file

@ -75,7 +75,7 @@ struct ContainsNonTrivial {
- (void)passNonTrivial:(NonTrivial)a;
@end
// CHECK: define{{.*}} void @_Z19testParamStrongWeak10StrongWeak(ptr dead_on_return noundef %{{.*}})
// CHECK: define{{.*}} void @_Z19testParamStrongWeak10StrongWeak(ptr noundef dead_on_return %{{.*}})
// CHECK: call noundef ptr @_ZN10StrongWeakD1Ev(
// CHECK-NEXT: ret void
@ -88,7 +88,7 @@ void testParamStrongWeak(StrongWeak a) {
// CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8
// CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8
// CHECK: %[[CALL:.*]] = call noundef ptr @_ZN10StrongWeakC1ERKS_(ptr {{[^,]*}} %[[AGG_TMP]], ptr noundef nonnull align 8 dereferenceable(16) %[[V0]])
// CHECK: call void @_Z19testParamStrongWeak10StrongWeak(ptr dead_on_return noundef %[[AGG_TMP]])
// CHECK: call void @_Z19testParamStrongWeak10StrongWeak(ptr noundef dead_on_return %[[AGG_TMP]])
// CHECK-NOT: call
// CHECK: ret void
@ -107,13 +107,13 @@ StrongWeak testReturnStrongWeak(StrongWeak *a) {
return *a;
}
// CHECK: define{{.*}} void @_Z27testParamContainsStrongWeak18ContainsStrongWeak(ptr dead_on_return noundef %[[A:.*]])
// CHECK: define{{.*}} void @_Z27testParamContainsStrongWeak18ContainsStrongWeak(ptr noundef dead_on_return %[[A:.*]])
// CHECK: call noundef ptr @_ZN18ContainsStrongWeakD1Ev(ptr {{[^,]*}} %[[A]])
void testParamContainsStrongWeak(ContainsStrongWeak a) {
}
// CHECK: define{{.*}} void @_Z26testParamDerivedStrongWeak17DerivedStrongWeak(ptr dead_on_return noundef %[[A:.*]])
// CHECK: define{{.*}} void @_Z26testParamDerivedStrongWeak17DerivedStrongWeak(ptr noundef dead_on_return %[[A:.*]])
// CHECK: call noundef ptr @_ZN17DerivedStrongWeakD1Ev(ptr {{[^,]*}} %[[A]])
void testParamDerivedStrongWeak(DerivedStrongWeak a) {
@ -163,7 +163,7 @@ Strong testReturnStrong(Strong *a) {
return *a;
}
// CHECK: define{{.*}} void @_Z21testParamWeakTemplate1SIU6__weakP11objc_objectE(ptr dead_on_return noundef %{{.*}})
// CHECK: define{{.*}} void @_Z21testParamWeakTemplate1SIU6__weakP11objc_objectE(ptr noundef dead_on_return %{{.*}})
// CHECK: call noundef ptr @_ZN1SIU6__weakP11objc_objectED1Ev(
// CHECK-NEXT: ret void
@ -237,7 +237,7 @@ void test0(C *c) {
// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8
// CHECK: br i1
// CHECK: call void @objc_msgSend({{.*}}, ptr dead_on_return noundef %[[AGG_TMP]])
// CHECK: call void @objc_msgSend({{.*}}, ptr noundef dead_on_return %[[AGG_TMP]])
// CHECK: br
// CHECK: %[[CALL1:.*]] = call noundef ptr @_ZN10StrongWeakD1Ev(ptr noundef nonnull align 8 dereferenceable(16) %[[AGG_TMP]])

View file

@ -60,7 +60,7 @@ struct CGRect {
// CHECK-LABEL: define{{.*}} i32 @main
// CHECK: call void @_ZN1SC1ERKS_(ptr {{[^,]*}} [[AGGTMP:%[a-zA-Z0-9\.]+]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) {{%[a-zA-Z0-9\.]+}})
// CHECK: call void @objc_msgSend(ptr noundef {{%[a-zA-Z0-9\.]+}}, ptr noundef {{%[a-zA-Z0-9\.]+}}, ptr dead_on_return noundef [[AGGTMP]])
// CHECK: call void @objc_msgSend(ptr noundef {{%[a-zA-Z0-9\.]+}}, ptr noundef {{%[a-zA-Z0-9\.]+}}, ptr noundef dead_on_return [[AGGTMP]])
// CHECK-NEXT: ret i32 0
int main() {
I *i;

View file

@ -15,7 +15,7 @@ struct AddrDiscStrong1 {
// Check that AddrDiscStrong0 is destructed in the callee.
// CHECK: define void @_Z24testParamAddrDiscStrong015AddrDiscStrong0(ptr dead_on_return noundef %[[A:.*]])
// CHECK: define void @_Z24testParamAddrDiscStrong015AddrDiscStrong0(ptr noundef dead_on_return %[[A:.*]])
// CHECK: call noundef ptr @_ZN15AddrDiscStrong0D1Ev(ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %[[A]])
// CHECK: ret void

View file

@ -4,7 +4,7 @@
// CHECK: @_ZN6pr96081xE ={{.*}} global ptr null, align 8, !dbg [[X:![0-9]+]]
// CHECK: define{{.*}} void @_ZN7pr147634funcENS_3fooE
// CHECK-SAME: ptr dead_on_return noundef [[param:%.*]])
// CHECK-SAME: ptr noundef dead_on_return [[param:%.*]])
// CHECK-NEXT: entry:
// CHECK-NEXT: alloca ptr, align 8
// CHECK-NEXT: [[param_addr_storage:%.*]] = alloca ptr, align 8

View file

@ -42,7 +42,7 @@ void testStrongException(void) {
// CHECK: call void @genWeak(ptr dead_on_unwind writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP]])
// CHECK: invoke void @genWeak(ptr dead_on_unwind writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP1]])
// CHECK: call void @calleeWeak(ptr dead_on_return noundef %[[AGG_TMP]], ptr dead_on_return noundef %[[AGG_TMP1]])
// CHECK: call void @calleeWeak(ptr noundef dead_on_return %[[AGG_TMP]], ptr noundef dead_on_return %[[AGG_TMP1]])
// CHECK: ret void
// CHECK: landingpad { ptr, i32 }

View file

@ -15,8 +15,8 @@
#include <stdarg.h>
// AARCH64-C: define {{.*}} @f(i32 noundef %n, ptr dead_on_return noundef %list)
// AARCH64-CXX: define {{.*}} @_Z1fiSt9__va_list(i32 noundef %n, ptr dead_on_return noundef %list)
// AARCH64-C: define {{.*}} @f(i32 noundef %n, ptr noundef dead_on_return %list)
// AARCH64-CXX: define {{.*}} @_Z1fiSt9__va_list(i32 noundef %n, ptr noundef dead_on_return %list)
// X86_64-C: define {{.*}} @f(i32 noundef %n, ptr noundef %list)
// X86_64-CXX: define {{.*}} @_Z1fiP13__va_list_tag(i32 noundef %n, ptr noundef %list)
// PPC64-C: define {{.*}} @f(i32 noundef signext %n, ptr noundef %list)

View file

@ -1841,20 +1841,26 @@ Currently, only the following parameter attributes are defined:
This attribute cannot be applied to return values.
``dead_on_return``
``dead_on_return`` or ``dead_on_return(<n>)``
This attribute indicates that the memory pointed to by the argument is dead
upon function return, both upon normal return and if the calls unwinds, meaning
that the caller will not depend on its contents. Stores that would be observable
either on the return path or on the unwind path may be elided.
either on the return path or on the unwind path may be elided. A number of
bytes known to be dead may optionally be provided in parentheses. If a number
of bytes is not specified, all memory reachable through the pointer is marked as
dead on return.
Specifically, the behavior is as-if any memory written through the pointer
during the execution of the function is overwritten with a poison value
upon function return. The caller may access the memory, but any load
not preceded by a store will return poison.
not preceded by a store will return poison. If a byte count is specified,
only writes within the specified range are overwritten with poison on
function return.
This attribute does not imply aliasing properties. For pointer arguments that
do not alias other memory locations, ``noalias`` attribute may be used in
conjunction. Conversely, this attribute always implies ``dead_on_unwind``.
conjunction. Conversely, this attribute always implies ``dead_on_unwind``. When
a byte count is specified, ``dead_on_unwind`` is implied only for that range.
This attribute cannot be applied to return values.

View file

@ -319,7 +319,9 @@ namespace llvm {
bool parseOptionalAlignment(MaybeAlign &Alignment,
bool AllowParens = false);
bool parseOptionalCodeModel(CodeModel::Model &model);
bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
bool parseOptionalAttrBytes(lltok::Kind AttrKind,
std::optional<uint64_t> &Bytes,
bool ErrorNoBytes = true);
bool parseOptionalUWTableKind(UWTableKind &Kind);
bool parseAllocKind(AllocFnKind &Kind);
std::optional<MemoryEffects> parseMemoryAttr();

View file

@ -78,8 +78,8 @@ public:
/// Return true if this argument has the byval attribute.
LLVM_ABI bool hasByValAttr() const;
/// Return true if this argument has the dead_on_return attribute.
LLVM_ABI bool hasDeadOnReturnAttr() const;
/// Returns information on the memory marked dead_on_return for the argument.
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const;
/// Return true if this argument has the byref attribute.
LLVM_ABI bool hasByRefAttr() const;

View file

@ -60,6 +60,40 @@ enum class AllocFnKind : uint64_t {
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Aligned)
};
class DeadOnReturnInfo {
public:
DeadOnReturnInfo() : DeadBytes(std::nullopt) {}
DeadOnReturnInfo(uint64_t DeadOnReturnBytes) : DeadBytes(DeadOnReturnBytes) {}
uint64_t getNumberOfDeadBytes() const {
assert(DeadBytes.has_value() &&
"This attribute does not specify a byte count. Did you forget to "
"check if the attribute covers all reachable memory?");
return DeadBytes.value();
}
bool coversAllReachableMemory() const { return !DeadBytes.has_value(); }
static DeadOnReturnInfo createFromIntValue(uint64_t Data) {
if (Data == std::numeric_limits<uint64_t>::max())
return DeadOnReturnInfo();
return DeadOnReturnInfo(Data);
}
uint64_t toIntValue() const {
if (DeadBytes.has_value())
return DeadBytes.value();
return std::numeric_limits<uint64_t>::max();
}
bool isZeroSized() const {
return DeadBytes.has_value() && DeadBytes.value() == 0;
}
private:
std::optional<uint64_t> DeadBytes;
};
//===----------------------------------------------------------------------===//
/// \class
/// Functions, function parameters, and return types can have attributes
@ -276,6 +310,11 @@ public:
/// dereferenceable attribute.
LLVM_ABI uint64_t getDereferenceableBytes() const;
/// Returns the number of dead_on_return bytes from the dead_on_return
/// attribute, or std::nullopt if all memory reachable through the pointer is
/// marked dead on return.
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const;
/// Returns the number of dereferenceable_or_null bytes from the
/// dereferenceable_or_null attribute.
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const;
@ -445,6 +484,7 @@ public:
LLVM_ABI MaybeAlign getAlignment() const;
LLVM_ABI MaybeAlign getStackAlignment() const;
LLVM_ABI uint64_t getDereferenceableBytes() const;
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo() const;
LLVM_ABI uint64_t getDereferenceableOrNullBytes() const;
LLVM_ABI Type *getByValType() const;
LLVM_ABI Type *getStructRetType() const;
@ -964,6 +1004,9 @@ public:
/// the return value.
LLVM_ABI uint64_t getRetDereferenceableOrNullBytes() const;
/// Get the number of dead_on_return bytes (or zero if unknown) of an arg.
LLVM_ABI DeadOnReturnInfo getDeadOnReturnInfo(unsigned Index) const;
/// Get the number of dereferenceable_or_null bytes (or zero if unknown) of an
/// arg.
LLVM_ABI uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const;
@ -1242,6 +1285,10 @@ public:
/// internally in Attribute.
LLVM_ABI AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
/// This turns the number of dead_on_return bytes into the form used
/// internally in Attribute.
LLVM_ABI AttrBuilder &addDeadOnReturnAttr(DeadOnReturnInfo Info);
/// This turns the number of dereferenceable_or_null bytes into the
/// form used internally in Attribute.
LLVM_ABI AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);

View file

@ -204,7 +204,7 @@ def NoFree : EnumAttr<"nofree", IntersectAnd, [FnAttr, ParamAttr]>;
def DeadOnUnwind : EnumAttr<"dead_on_unwind", IntersectAnd, [ParamAttr]>;
/// Argument is dead upon function return.
def DeadOnReturn : EnumAttr<"dead_on_return", IntersectAnd, [ParamAttr]>;
def DeadOnReturn : IntAttr<"dead_on_return", IntersectMin, [ParamAttr]>;
/// Disable implicit floating point insts.
def NoImplicitFloat : EnumAttr<"noimplicitfloat", IntersectPreserve, [FnAttr]>;

View file

@ -523,6 +523,12 @@ public:
return AttributeSets.getParamDereferenceableBytes(ArgNo);
}
/// Extract the number of dead_on_return bytes for a parameter.
/// @param ArgNo Index of an argument, with 0 being the first function arg.
DeadOnReturnInfo getDeadOnReturnInfo(unsigned ArgNo) const {
return AttributeSets.getDeadOnReturnInfo(ArgNo);
}
/// Extract the number of dereferenceable_or_null bytes for a
/// parameter.
/// @param ArgNo AttributeList ArgNo, referring to an argument.

View file

@ -20,6 +20,7 @@
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
@ -1606,17 +1607,31 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
return false;
}
case Attribute::Dereferenceable: {
uint64_t Bytes;
if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
std::optional<uint64_t> Bytes;
if (parseOptionalAttrBytes(lltok::kw_dereferenceable, Bytes))
return true;
B.addDereferenceableAttr(Bytes);
assert(Bytes.has_value());
B.addDereferenceableAttr(Bytes.value());
return false;
}
case Attribute::DeadOnReturn: {
std::optional<uint64_t> Bytes;
if (parseOptionalAttrBytes(lltok::kw_dead_on_return, Bytes,
/*ErrorNoBytes=*/false))
return true;
if (Bytes.has_value()) {
B.addDeadOnReturnAttr(DeadOnReturnInfo(Bytes.value()));
} else {
B.addDeadOnReturnAttr(DeadOnReturnInfo());
}
return false;
}
case Attribute::DereferenceableOrNull: {
uint64_t Bytes;
if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
std::optional<uint64_t> Bytes;
if (parseOptionalAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
return true;
B.addDereferenceableOrNullAttr(Bytes);
assert(Bytes.has_value());
B.addDereferenceableOrNullAttr(Bytes.value());
return false;
}
case Attribute::UWTable: {
@ -2468,31 +2483,38 @@ bool LLParser::parseOptionalCodeModel(CodeModel::Model &model) {
return false;
}
/// parseOptionalDerefAttrBytes
/// parseOptionalAttrBytes
/// ::= /* empty */
/// ::= AttrKind '(' 4 ')'
///
/// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'.
bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind,
uint64_t &Bytes) {
/// where AttrKind is either 'dereferenceable', 'dereferenceable_or_null', or
/// 'dead_on_return'
bool LLParser::parseOptionalAttrBytes(lltok::Kind AttrKind,
std::optional<uint64_t> &Bytes,
bool ErrorNoBytes) {
assert((AttrKind == lltok::kw_dereferenceable ||
AttrKind == lltok::kw_dereferenceable_or_null) &&
AttrKind == lltok::kw_dereferenceable_or_null ||
AttrKind == lltok::kw_dead_on_return) &&
"contract!");
Bytes = 0;
if (!EatIfPresent(AttrKind))
return false;
LocTy ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::lparen))
return error(ParenLoc, "expected '('");
if (!EatIfPresent(lltok::lparen)) {
if (ErrorNoBytes)
return error(ParenLoc, "expected '('");
Bytes = std::nullopt;
return false;
}
LocTy DerefLoc = Lex.getLoc();
if (parseUInt64(Bytes))
if (parseUInt64(Bytes.value()))
return true;
ParenLoc = Lex.getLoc();
if (!EatIfPresent(lltok::rparen))
return error(ParenLoc, "expected ')'");
if (!Bytes)
return error(DerefLoc, "dereferenceable bytes must be non-zero");
if (!Bytes.value())
return error(DerefLoc, "byte count specified must be non-zero");
return false;
}

View file

@ -2384,6 +2384,8 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addInAllocaAttr(nullptr);
else if (Kind == Attribute::UWTable)
B.addUWTableAttr(UWTableKind::Default);
else if (Kind == Attribute::DeadOnReturn)
B.addDeadOnReturnAttr(DeadOnReturnInfo());
else if (Attribute::isEnumAttrKind(Kind))
B.addAttribute(Kind);
else
@ -2402,6 +2404,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addDereferenceableAttr(Record[++i]);
else if (Kind == Attribute::DereferenceableOrNull)
B.addDereferenceableOrNullAttr(Record[++i]);
else if (Kind == Attribute::DeadOnReturn)
B.addDeadOnReturnAttr(
DeadOnReturnInfo::createFromIntValue(Record[++i]));
else if (Kind == Attribute::AllocSize)
B.addAllocSizeAttrFromRawRepr(Record[++i]);
else if (Kind == Attribute::VScaleRange)

View file

@ -332,6 +332,7 @@ public:
MaybeAlign getAlignment() const;
MaybeAlign getStackAlignment() const;
uint64_t getDereferenceableBytes() const;
DeadOnReturnInfo getDeadOnReturnInfo() const;
uint64_t getDereferenceableOrNullBytes() const;
std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
const;

View file

@ -451,6 +451,13 @@ uint64_t Attribute::getDereferenceableBytes() const {
return pImpl->getValueAsInt();
}
DeadOnReturnInfo Attribute::getDeadOnReturnInfo() const {
assert(hasAttribute(Attribute::DeadOnReturn) &&
"Trying to get dead_on_return bytes from"
"a parameter without such an attribute!");
return DeadOnReturnInfo::createFromIntValue(pImpl->getValueAsInt());
}
uint64_t Attribute::getDereferenceableOrNullBytes() const {
assert(hasAttribute(Attribute::DereferenceableOrNull) &&
"Trying to get dereferenceable bytes from "
@ -573,6 +580,13 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (hasAttribute(Attribute::DereferenceableOrNull))
return AttrWithBytesToString("dereferenceable_or_null");
if (hasAttribute(Attribute::DeadOnReturn)) {
uint64_t DeadBytes = getValueAsInt();
if (DeadBytes == std::numeric_limits<uint64_t>::max())
return "dead_on_return";
return AttrWithBytesToString("dead_on_return");
}
if (hasAttribute(Attribute::AllocSize)) {
unsigned ElemSize;
std::optional<unsigned> NumElems;
@ -1156,6 +1170,10 @@ uint64_t AttributeSet::getDereferenceableBytes() const {
return SetNode ? SetNode->getDereferenceableBytes() : 0;
}
DeadOnReturnInfo AttributeSet::getDeadOnReturnInfo() const {
return SetNode ? SetNode->getDeadOnReturnInfo() : DeadOnReturnInfo(0);
}
uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
}
@ -1360,6 +1378,12 @@ uint64_t AttributeSetNode::getDereferenceableBytes() const {
return 0;
}
DeadOnReturnInfo AttributeSetNode::getDeadOnReturnInfo() const {
if (auto A = findEnumAttribute(Attribute::DeadOnReturn))
return A->getDeadOnReturnInfo();
return 0;
}
uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
return A->getDereferenceableOrNullBytes();
@ -1977,6 +2001,10 @@ uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
return getRetAttrs().getDereferenceableOrNullBytes();
}
DeadOnReturnInfo AttributeList::getDeadOnReturnInfo(unsigned Index) const {
return getParamAttrs(Index).getDeadOnReturnInfo();
}
uint64_t
AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
return getParamAttrs(Index).getDereferenceableOrNullBytes();
@ -2199,6 +2227,13 @@ AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
return addRawIntAttr(Attribute::Dereferenceable, Bytes);
}
AttrBuilder &AttrBuilder::addDeadOnReturnAttr(DeadOnReturnInfo Info) {
if (Info.isZeroSized())
return *this;
return addRawIntAttr(Attribute::DeadOnReturn, Info.toIntValue());
}
AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
if (Bytes == 0)
return *this;

View file

@ -130,10 +130,9 @@ bool Argument::hasByValAttr() const {
return hasAttribute(Attribute::ByVal);
}
bool Argument::hasDeadOnReturnAttr() const {
if (!getType()->isPointerTy())
return false;
return hasAttribute(Attribute::DeadOnReturn);
DeadOnReturnInfo Argument::getDeadOnReturnInfo() const {
assert(getType()->isPointerTy() && "Only pointers have dead_on_return bytes");
return getParent()->getDeadOnReturnInfo(getArgNo());
}
bool Argument::hasByRefAttr() const {

View file

@ -1017,7 +1017,9 @@ struct DSEState {
// Treat byval, inalloca or dead on return arguments the same as Allocas,
// stores to them are dead at the end of the function.
for (Argument &AI : F.args())
if (AI.hasPassPointeeByValueCopyAttr() || AI.hasDeadOnReturnAttr())
if (AI.hasPassPointeeByValueCopyAttr() ||
(AI.getType()->isPointerTy() &&
AI.getDeadOnReturnInfo().coversAllReachableMemory()))
InvisibleToCallerAfterRet.insert({&AI, true});
// Collect whether there is any irreducible control flow in the function.

Some files were not shown because too many files have changed in this diff Show more