[llvm-branch-commits] [clang] [Clang] Fix __builtin_clear_padding() for bitfields (PR #216063)
Victor Campos via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 13 07:24:39 PDT 2026
https://github.com/vhscampos created https://github.com/llvm/llvm-project/pull/216063
This patch fixes the padding clearing logic for bitfields.
The padding clearing logic for bitfields is wrong for these cases:
- Over-sized bitfields don't have their padding bits recognised as such.
- In big endian mode, the occupied bits are wrongly determined because the different byte order is dismissed.
Assisted-by: Codex. Used to help debugging.
>From f6b309b001ece9bfdb67586c125ea37b9094ccd5 Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Wed, 5 Aug 2026 16:05:21 +0100
Subject: [PATCH] [Clang] Fix __builtin_clear_padding() for bitfields
This patch fixes the padding clearing logic for bitfields.
The padding clearing logic for bitfields is wrong for these cases:
- Over-sized bitfields don't have their padding bits recognised as
such.
- In big endian mode, the occupied bits are wrongly determined because
the different byte order is dismissed.
Assisted-by: Codex. Used to help debugging.
---
clang/lib/CodeGen/CGBuiltin.cpp | 70 +-
.../CodeGen/builtin-clear-padding-codegen.c | 1967 ++++++++++-
.../builtin-clear-padding-codegen.cpp | 3015 ++++++++++++++++-
3 files changed, 4916 insertions(+), 136 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 13aff2ef13eb9..24b2987923e26 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2672,6 +2672,69 @@ struct PaddingClearer {
return CGF.getContext().getTypeSize(Ty);
}
+ /// Compute the occupied bit intervals for a bitfield.
+ ///
+ /// In the case of little endian, the occupied bits are always contiguous so a
+ /// single interval is sufficient; whereas in big endian mode, the occupied
+ /// bits are not necessarily contiguous since the byte order is reversed. Care
+ /// is also taken if the bitfield is volatile because the field size and
+ /// offset can be different in this case.
+ SmallVector<BitInterval>
+ computeBitfieldOccupiedIntervals(const RecordDecl *RD, const FieldDecl *Field,
+ uint64_t StartBitOffset) const {
+ const CGRecordLayout &Layout = CGF.CGM.getTypes().getCGRecordLayout(RD);
+ const CGBitFieldInfo &Info = Layout.getBitFieldInfo(Field);
+ bool IsLittleEndian = CGF.getTarget().isLittleEndian();
+ bool IsVolatile = Field->getType().isVolatileQualified() &&
+ Info.VolatileStorageSize != 0 &&
+ CGF.CGM.getTarget().getABI().starts_with("aapcs");
+
+ uint64_t DeclaredTySizeInBits =
+ getScalarOccupiedSizeInBits(Field->getType());
+ // In case of over-sized bitfields, the number of bits actually occupied
+ // with values is smaller than the declared bitfield width (Info.Size).
+ uint64_t ValueSizeInBits =
+ std::min(static_cast<uint64_t>(Info.Size), DeclaredTySizeInBits);
+
+ const uint64_t Offset = IsVolatile ? Info.VolatileOffset : Info.Offset;
+
+ // This calculation looks different between volatile and non-volatile
+ // because StorageOffset is in bytes, whereas VolatileStorageOffset is in
+ // VolatileStorageSize units.
+ const uint64_t StorageOffset =
+ IsVolatile ? Info.VolatileStorageOffset.getQuantity() *
+ Info.VolatileStorageSize
+ : CGF.getContext().toBits(Info.StorageOffset);
+
+ if (IsLittleEndian)
+ return {BitInterval{StartBitOffset + StorageOffset + Offset,
+ StartBitOffset + StorageOffset + Offset +
+ ValueSizeInBits}};
+
+ const uint64_t StorageSize =
+ IsVolatile ? Info.VolatileStorageSize : Info.StorageSize;
+ const uint64_t BitsInByte = CGF.getContext().getCharWidth();
+
+ SmallVector<BitInterval> Intervals;
+
+ for (uint64_t Start = Offset, End = Start + ValueSizeInBits; Start < End;
+ Start = (Start + BitsInByte) & (~0UL << 3)) {
+ uint64_t ByteBoundaryStart = Start & (~0UL << 3);
+ uint64_t ByteBoundaryEnd = ByteBoundaryStart + BitsInByte;
+ uint64_t OffsetWithinByte = Start - ByteBoundaryStart;
+ uint64_t SizeWithinByte =
+ std::min(End - Start, BitsInByte - OffsetWithinByte);
+ uint64_t ByteOffset = StorageSize - ByteBoundaryEnd;
+
+ BitInterval BI{StartBitOffset + StorageOffset + ByteOffset +
+ OffsetWithinByte,
+ StartBitOffset + StorageOffset + ByteOffset +
+ OffsetWithinByte + SizeWithinByte};
+ Intervals.push_back(std::move(BI));
+ }
+ return Intervals;
+ }
+
/// Compute the occupied bit intervals for a BitInt.
///
/// In the case of little endian, the occupied bits are always contiguous so a
@@ -2816,12 +2879,11 @@ struct PaddingClearer {
if (Field->isUnnamedBitField())
continue;
- auto FieldOffset = ASTLayout.getFieldOffset(Field->getFieldIndex());
if (Field->isBitField()) {
- OccuppiedIntervals.push_back(BitInterval{
- StartBitOffset + FieldOffset,
- StartBitOffset + FieldOffset + Field->getBitWidthValue()});
+ OccuppiedIntervals.append(
+ computeBitfieldOccupiedIntervals(R, Field, StartBitOffset));
} else {
+ auto FieldOffset = ASTLayout.getFieldOffset(Field->getFieldIndex());
Stack.push_back(Data{StartBitOffset + FieldOffset, Field->getType(),
/*VisitVirtualBase*/ true});
}
diff --git a/clang/test/CodeGen/builtin-clear-padding-codegen.c b/clang/test/CodeGen/builtin-clear-padding-codegen.c
index fceb7b623ba6d..7e709f4fcbf98 100644
--- a/clang/test/CodeGen/builtin-clear-padding-codegen.c
+++ b/clang/test/CodeGen/builtin-clear-padding-codegen.c
@@ -3,8 +3,8 @@
// RUN: %clang_cc1 -std=c11 -triple=x86_64-pc-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=WINDOWS
// RUN: %clang_cc1 -std=c11 -triple=armv7a-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-LE
// RUN: %clang_cc1 -std=c11 -triple=armebv7a-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-BE
-// RUN: %clang_cc1 -std=c11 -triple=aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-LE
-// RUN: %clang_cc1 -std=c11 -triple=aarch64_be-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-BE
+// RUN: %clang_cc1 -std=c11 -triple=aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=AARCH64-LE
+// RUN: %clang_cc1 -std=c11 -triple=aarch64_be-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=AARCH64-BE
struct Empty {};
@@ -31,6 +31,38 @@ struct Empty {};
// WINDOWS-NEXT: store i8 0, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testEmpty(
+// ARM-LE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testEmpty(
+// ARM-BE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testEmpty(
+// AARCH64-LE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testEmpty(
+// AARCH64-BE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testEmpty(struct Empty *e) {
// Emtpy struct is empty in C in Itanium ABI, no padding
// Emtpy struct has 4 bytes in C in clang's MSVC ABI
@@ -53,6 +85,38 @@ void testEmpty(struct Empty *e) {
// WINDOWS-NEXT: %0 = load ptr, ptr %i.addr, align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testPrimitiveNoPadding(
+// ARM-LE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testPrimitiveNoPadding(
+// ARM-BE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testPrimitiveNoPadding(
+// AARCH64-LE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testPrimitiveNoPadding(
+// AARCH64-BE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testPrimitiveNoPadding(int *i) {
// This should not clear any padding, since int has no padding.
__builtin_clear_padding(i);
@@ -86,6 +150,38 @@ void testPrimitiveNoPadding(int *i) {
// WINDOWS-NEXT: %0 = load ptr, ptr %ld.addr, align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testPrimitiveLongDouble(
+// ARM-LE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testPrimitiveLongDouble(
+// ARM-BE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testPrimitiveLongDouble(
+// AARCH64-LE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testPrimitiveLongDouble(
+// AARCH64-BE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testPrimitiveLongDouble(long double *ld) {
// padding [10, 15] on x86
__builtin_clear_padding(ld);
@@ -127,82 +223,254 @@ void testPrimitiveLongDouble(long double *ld) {
// WINDOWS-NEXT: ret void
//
// ARM-LE-LABEL: define dso_local void @testBitInt(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE12:%.*]] = getelementptr i8, ptr [[OBJ]], i32 12
-// ARM-LE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-LE-NEXT: store i8 [[MASKED]], ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[BYTE13:%.*]] = getelementptr i8, ptr [[OBJ]], i32 13
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE13]], align 1
-// ARM-LE-NEXT: [[BYTE14:%.*]] = getelementptr i8, ptr [[OBJ]], i32 14
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE14]], align 2
-// ARM-LE-NEXT: [[BYTE15:%.*]] = getelementptr i8, ptr [[OBJ]], i32 15
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE15]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @testBitInt(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE1:%.*]] = getelementptr i8, ptr [[OBJ]], i32 1
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE1]], align 1
-// ARM-BE-NEXT: [[BYTE2:%.*]] = getelementptr i8, ptr [[OBJ]], i32 2
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE2]], align 2
-// ARM-BE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-BE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-BE-NEXT: store i8 [[MASKED]], ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testBitInt(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testBitInt(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testBitInt(_BitInt(97) *bi) {
// Storage is widened to 128 bits; clear bits [97, 128).
__builtin_clear_padding(bi);
}
+// LINUX-LABEL: define dso_local void @testBitIntByteAligned(
+// LINUX-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// LINUX-NEXT: [[ENTRY:.*:]]
+// LINUX-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// LINUX-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// LINUX-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// LINUX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// LINUX-NEXT: store i8 0, ptr [[TMP1]], align 1
+// LINUX-NEXT: ret void
+//
+// WINDOWS-LABEL: define dso_local void @testBitIntByteAligned(
+// WINDOWS-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// WINDOWS-NEXT: [[ENTRY:.*:]]
+// WINDOWS-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// WINDOWS-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// WINDOWS-NEXT: store i8 0, ptr [[TMP1]], align 1
+// WINDOWS-NEXT: ret void
+//
// ARM-LE-LABEL: define dso_local void @testBitIntByteAligned(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE3]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @testBitIntByteAligned(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align 4
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testBitIntByteAligned(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testBitIntByteAligned(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: ret void
//
void testBitIntByteAligned(_BitInt(24) *bi) {
// Storage is widened to 32 bits; clear the leading or trailing byte.
__builtin_clear_padding(bi);
}
+// LINUX-LABEL: define dso_local void @testVolatileBitInt(
+// LINUX-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// LINUX-NEXT: [[ENTRY:.*:]]
+// LINUX-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// LINUX-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// LINUX-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// LINUX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// LINUX-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// LINUX-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// LINUX-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// LINUX-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// LINUX-NEXT: store i8 0, ptr [[TMP4]], align 1
+// LINUX-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// LINUX-NEXT: store i8 0, ptr [[TMP5]], align 2
+// LINUX-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// LINUX-NEXT: store i8 0, ptr [[TMP6]], align 1
+// LINUX-NEXT: ret void
+//
+// WINDOWS-LABEL: define dso_local void @testVolatileBitInt(
+// WINDOWS-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// WINDOWS-NEXT: [[ENTRY:.*:]]
+// WINDOWS-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// WINDOWS-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// WINDOWS-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// WINDOWS-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// WINDOWS-NEXT: store i8 0, ptr [[TMP4]], align 1
+// WINDOWS-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// WINDOWS-NEXT: store i8 0, ptr [[TMP5]], align 2
+// WINDOWS-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// WINDOWS-NEXT: store i8 0, ptr [[TMP6]], align 1
+// WINDOWS-NEXT: ret void
+//
// ARM-LE-LABEL: define dso_local void @testVolatileBitInt(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE12:%.*]] = getelementptr i8, ptr [[OBJ]], i32 12
-// ARM-LE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-LE-NEXT: store i8 [[MASKED]], ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[BYTE13:%.*]] = getelementptr i8, ptr [[OBJ]], i32 13
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE13]], align 1
-// ARM-LE-NEXT: [[BYTE14:%.*]] = getelementptr i8, ptr [[OBJ]], i32 14
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE14]], align 2
-// ARM-LE-NEXT: [[BYTE15:%.*]] = getelementptr i8, ptr [[OBJ]], i32 15
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE15]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @testVolatileBitInt(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE1:%.*]] = getelementptr i8, ptr [[OBJ]], i32 1
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE1]], align 1
-// ARM-BE-NEXT: [[BYTE2:%.*]] = getelementptr i8, ptr [[OBJ]], i32 2
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE2]], align 2
-// ARM-BE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-BE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-BE-NEXT: store i8 [[MASKED]], ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testVolatileBitInt(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testVolatileBitInt(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testVolatileBitInt(volatile _BitInt(97) *bi) {
__builtin_clear_padding(bi);
@@ -248,6 +516,38 @@ void testVolatileBitInt(volatile _BitInt(97) *bi) {
// WINDOWS-NEXT: %0 = load ptr, ptr %c.addr, align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testPrimitiveComplexLongDouble(
+// ARM-LE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testPrimitiveComplexLongDouble(
+// ARM-BE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testPrimitiveComplexLongDouble(
+// AARCH64-LE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testPrimitiveComplexLongDouble(
+// AARCH64-BE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testPrimitiveComplexLongDouble(_Complex long double *c) {
// padding [10, 15] and [26, 31] on x86
__builtin_clear_padding(c);
@@ -273,6 +573,38 @@ union U1 {
// WINDOWS-NEXT: %0 = load ptr, ptr %u.addr, align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnionDifferentLength(
+// ARM-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnionDifferentLength(
+// ARM-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnionDifferentLength(
+// AARCH64-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnionDifferentLength(
+// AARCH64-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testUnionDifferentLength(union U1 *u) {
// This should not clear the object representation bits of the non-active member.
__builtin_clear_padding(u);
@@ -330,6 +662,94 @@ union U2 {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnionTailPaddingOfLongestMember(
+// ARM-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnionTailPaddingOfLongestMember(
+// ARM-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnionTailPaddingOfLongestMember(
+// AARCH64-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnionTailPaddingOfLongestMember(
+// AARCH64-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnionTailPaddingOfLongestMember(union U2 *u) {
// This should clear the tail padding of the longest member.
// [1 - 7]
@@ -402,6 +822,94 @@ struct __attribute__((aligned(4))) Baz {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testStructPaddingInBetweenMembers(
+// ARM-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testStructPaddingInBetweenMembers(
+// ARM-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testStructPaddingInBetweenMembers(
+// AARCH64-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testStructPaddingInBetweenMembers(
+// AARCH64-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testStructPaddingInBetweenMembers(struct Baz *baz) {
// this should clear all the padding in between various members
__builtin_clear_padding(baz);
@@ -450,6 +958,94 @@ void testStructPaddingInBetweenMembers(struct Baz *baz) {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testStructVolatile(
+// ARM-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testStructVolatile(
+// ARM-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testStructVolatile(
+// AARCH64-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testStructVolatile(
+// AARCH64-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testStructVolatile(volatile struct Baz *baz) {
// this should clear all the padding in between various members
__builtin_clear_padding(baz);
@@ -534,6 +1130,126 @@ struct S3 {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testStructWithLongDouble(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 10
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testStructWithLongDouble(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 10
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testStructWithLongDouble(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 17
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 18
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 19
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 20
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 21
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 8
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 4
+// AARCH64-LE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP13]], align 1
+// AARCH64-LE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP14]], align 2
+// AARCH64-LE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testStructWithLongDouble(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 17
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 18
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 19
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 20
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 21
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 8
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP13]], align 1
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP14]], align 2
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testStructWithLongDouble(struct S3 *s) {
// "long double data[0-9]", PAD [10-15], "b", PAD [17-31]
__builtin_clear_padding(s);
@@ -570,6 +1286,54 @@ struct S11 {
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testBitFields(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testBitFields(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -8
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testBitFields(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testBitFields(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -8
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testBitFields(struct S11 *s) {
// "b1" [0-2], "b2" [3-4], PAD [5-7], "b3" [8-13], "b4" [14-15]
// to clear 5-7, we should AND 0b00011111 (31)
@@ -577,6 +1341,285 @@ void testBitFields(struct S11 *s) {
}
+struct VolatileBitfield {
+ volatile unsigned char a : 5;
+ int b : 7;
+ volatile int c : 27;
+};
+
+// LINUX-LABEL: define dso_local void @testVolatileBitfields(
+// LINUX-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// LINUX-NEXT: [[ENTRY:.*:]]
+// LINUX-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// LINUX-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// LINUX-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// LINUX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// LINUX-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// LINUX-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// LINUX-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// LINUX-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// LINUX-NEXT: store i8 0, ptr [[TMP4]], align 2
+// LINUX-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// LINUX-NEXT: store i8 0, ptr [[TMP5]], align 1
+// LINUX-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// LINUX-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// LINUX-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// LINUX-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// LINUX-NEXT: ret void
+//
+// WINDOWS-LABEL: define dso_local void @testVolatileBitfields(
+// WINDOWS-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// WINDOWS-NEXT: [[ENTRY:.*:]]
+// WINDOWS-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// WINDOWS-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// WINDOWS-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// WINDOWS-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// WINDOWS-NEXT: store i8 0, ptr [[TMP4]], align 1
+// WINDOWS-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// WINDOWS-NEXT: store i8 0, ptr [[TMP5]], align 2
+// WINDOWS-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// WINDOWS-NEXT: store i8 0, ptr [[TMP6]], align 1
+// WINDOWS-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// WINDOWS-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// WINDOWS-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 127
+// WINDOWS-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// WINDOWS-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// WINDOWS-NEXT: store i8 0, ptr [[TMP10]], align 1
+// WINDOWS-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// WINDOWS-NEXT: store i8 0, ptr [[TMP11]], align 2
+// WINDOWS-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// WINDOWS-NEXT: store i8 0, ptr [[TMP12]], align 1
+// WINDOWS-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// WINDOWS-NEXT: [[TMP14:%.*]] = load i8, ptr [[TMP13]], align 1
+// WINDOWS-NEXT: [[TMP15:%.*]] = and i8 [[TMP14]], 7
+// WINDOWS-NEXT: store i8 [[TMP15]], ptr [[TMP13]], align 1
+// WINDOWS-NEXT: ret void
+//
+// ARM-LE-LABEL: define dso_local void @testVolatileBitfields(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// ARM-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testVolatileBitfields(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// ARM-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testVolatileBitfields(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// AARCH64-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testVolatileBitfields(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileBitfields(struct VolatileBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+// LINUX-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// LINUX-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// LINUX-NEXT: [[ENTRY:.*:]]
+// LINUX-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// LINUX-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// LINUX-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// LINUX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// LINUX-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// LINUX-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// LINUX-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// LINUX-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// LINUX-NEXT: store i8 0, ptr [[TMP4]], align 2
+// LINUX-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// LINUX-NEXT: store i8 0, ptr [[TMP5]], align 1
+// LINUX-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// LINUX-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// LINUX-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// LINUX-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// LINUX-NEXT: ret void
+//
+// WINDOWS-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// WINDOWS-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// WINDOWS-NEXT: [[ENTRY:.*:]]
+// WINDOWS-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// WINDOWS-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// WINDOWS-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// WINDOWS-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// WINDOWS-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// WINDOWS-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// WINDOWS-NEXT: store i8 0, ptr [[TMP4]], align 1
+// WINDOWS-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// WINDOWS-NEXT: store i8 0, ptr [[TMP5]], align 2
+// WINDOWS-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// WINDOWS-NEXT: store i8 0, ptr [[TMP6]], align 1
+// WINDOWS-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// WINDOWS-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// WINDOWS-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 127
+// WINDOWS-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// WINDOWS-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// WINDOWS-NEXT: store i8 0, ptr [[TMP10]], align 1
+// WINDOWS-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// WINDOWS-NEXT: store i8 0, ptr [[TMP11]], align 2
+// WINDOWS-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// WINDOWS-NEXT: store i8 0, ptr [[TMP12]], align 1
+// WINDOWS-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// WINDOWS-NEXT: [[TMP14:%.*]] = load i8, ptr [[TMP13]], align 1
+// WINDOWS-NEXT: [[TMP15:%.*]] = and i8 [[TMP14]], 7
+// WINDOWS-NEXT: store i8 [[TMP15]], ptr [[TMP13]], align 1
+// WINDOWS-NEXT: ret void
+//
+// ARM-LE-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// ARM-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// ARM-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// AARCH64-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testVolatileBitfieldsVolatileStruct(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileBitfieldsVolatileStruct(volatile struct VolatileBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+
// LINUX-LABEL: define dso_local void @testArrayNoPadding(
// LINUX-SAME: ) #[[ATTR0]] {
// LINUX-NEXT: [[ENTRY:.*:]]
@@ -588,6 +1631,30 @@ void testBitFields(struct S11 *s) {
// WINDOWS-NEXT: %i = alloca [4 x i32], align 4
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testArrayNoPadding(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testArrayNoPadding(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testArrayNoPadding(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testArrayNoPadding(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// AARCH64-BE-NEXT: ret void
+//
void testArrayNoPadding(void) {
int i[4];
// there is no padding in the array.
@@ -629,6 +1696,30 @@ void testArrayNoPadding(void) {
// WINDOWS-NEXT: %ld = alloca [2 x double], align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testArrayLongDouble(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[LD:%.*]] = alloca [2 x double], align 8
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testArrayLongDouble(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[LD:%.*]] = alloca [2 x double], align 8
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testArrayLongDouble(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[LD:%.*]] = alloca [2 x fp128], align 16
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testArrayLongDouble(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[LD:%.*]] = alloca [2 x fp128], align 16
+// AARCH64-BE-NEXT: ret void
+//
void testArrayLongDouble() {
// long double 0, [0-9] PAD [10-15]
// long double 1, [16-25] PAD [26-31]
@@ -695,6 +1786,126 @@ void testArrayLongDouble() {
// WINDOWS-NEXT: store i8 0, ptr %11, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testArrayOfStruct(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_LOCAL:%.*]]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// ARM-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// ARM-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testArrayOfStruct(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_LOCAL:%.*]]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// ARM-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// ARM-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testArrayOfStruct(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_LOCAL:%.*]]], align 4
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testArrayOfStruct(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_LOCAL:%.*]]], align 4
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testArrayOfStruct(void) {
struct S_local {
int i1;
@@ -751,6 +1962,70 @@ struct ArrOfStructsWithPadding {
// WINDOWS-NEXT: store i8 0, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testArrOfStructsWithPadding(
+// ARM-LE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testArrOfStructsWithPadding(
+// ARM-BE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testArrOfStructsWithPadding(
+// AARCH64-LE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testArrOfStructsWithPadding(
+// AARCH64-BE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testArrOfStructsWithPadding(struct ArrOfStructsWithPadding *arr) {
__builtin_clear_padding(arr);
}
@@ -778,6 +2053,54 @@ void testArrOfStructsWithPadding(struct ArrOfStructsWithPadding *arr) {
// WINDOWS-NEXT: store i8 0, ptr %2, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testAtomic(
+// ARM-LE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testAtomic(
+// ARM-BE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testAtomic(
+// AARCH64-LE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testAtomic(
+// AARCH64-BE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAtomic(_Atomic(struct Bar)* bar) {
__builtin_clear_padding(bar);
}
@@ -816,6 +2139,70 @@ typedef long double LongDouble3Vec __attribute__((ext_vector_type(3)));
// WINDOWS-NEXT: store i8 0, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testAttributedType(
+// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testAttributedType(
+// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testAttributedType(
+// AARCH64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testAttributedType(
+// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAttributedType(Float3Vec* v) {
__builtin_clear_padding(v);
}
@@ -919,6 +2306,134 @@ void testAttributedType(Float3Vec* v) {
// WINDOWS-NEXT: store i8 0, ptr %8, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testAttributedLongDoubleType(
+// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// ARM-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testAttributedLongDoubleType(
+// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testAttributedLongDoubleType(
+// AARCH64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 49
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 50
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 51
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 52
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 53
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 54
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 55
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 56
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 8
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 57
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 58
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 59
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-LE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 60
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP13]], align 4
+// AARCH64-LE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 61
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP14]], align 1
+// AARCH64-LE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 62
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP15]], align 2
+// AARCH64-LE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 63
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP16]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testAttributedLongDoubleType(
+// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 49
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 50
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 51
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 52
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 53
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 54
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 55
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 56
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 57
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 58
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 59
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 60
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP13]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 61
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP14]], align 1
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 62
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 2
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 63
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAttributedLongDoubleType(LongDouble3Vec *v) {
// long double elements occupy [0-9], [16-25], [32-41] on x86.
__builtin_clear_padding(v);
@@ -953,6 +2468,54 @@ struct UnnamedBitfieldSingleBit {
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnnamedBitfieldSingleBit(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -9
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnnamedBitfieldSingleBit(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -17
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnnamedBitfieldSingleBit(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -9
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnnamedBitfieldSingleBit(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -17
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedBitfieldSingleBit(struct UnnamedBitfieldSingleBit *s) {
// byte 0: a[bits 0-2], unnamed[bit 3], b[bits 4-7]
// bit 3 must be cleared
@@ -989,6 +2552,54 @@ struct UnnamedBitfieldMiddle {
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnnamedBitfieldMiddle(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnnamedBitfieldMiddle(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnnamedBitfieldMiddle(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnnamedBitfieldMiddle(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedBitfieldMiddle(struct UnnamedBitfieldMiddle *s) {
// byte 0: a[0-2], unnamed[3-4], b[5-7]
// bits 3-4 must be cleared
@@ -1033,6 +2644,70 @@ struct UnnamedBitfieldSurrounding {
// WINDOWS-NEXT: store i8 %6, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnnamedBitfieldSurrounding(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// ARM-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnnamedBitfieldSurrounding(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnnamedBitfieldSurrounding(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// AARCH64-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnnamedBitfieldSurrounding(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedBitfieldSurrounding(struct UnnamedBitfieldSurrounding *s) {
// byte 0: unnamed[0-1], a[2-5], unnamed[6-7]
// bits 0-1 and 6-7 must be cleared
@@ -1103,6 +2778,118 @@ struct UnnamedZeroWidthBitfield {
// WINDOWS-NEXT: store i8 0, ptr %12, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnnamedZeroWidthBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-LE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// ARM-LE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15
+// ARM-LE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// ARM-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// ARM-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// ARM-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnnamedZeroWidthBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// ARM-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], -16
+// ARM-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// ARM-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// ARM-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnnamedZeroWidthBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnnamedZeroWidthBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedZeroWidthBitfield(struct UnnamedZeroWidthBitfield *s) {
// byte 0: a[0-3], unnamed[4-7]
// bytes 1-3: struct padding
@@ -1157,6 +2944,70 @@ struct UnnamedBitfieldMultiByte {
// WINDOWS-NEXT: store i8 %6, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @testUnnamedBitfieldMultiByte(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -16
+// ARM-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @testUnnamedBitfieldMultiByte(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 15
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @testUnnamedBitfieldMultiByte(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -16
+// AARCH64-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @testUnnamedBitfieldMultiByte(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 15
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedBitfieldMultiByte(struct UnnamedBitfieldMultiByte *s) {
// 2 bytes: a[0-3], unnamed[4-11], b[12-15]
// byte 0: clear bits 4-7
diff --git a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp
index bd52b0e10662e..110c012395f11 100644
--- a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp
+++ b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp
@@ -1,10 +1,11 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// NOTE: WINDOWS checks are maintained manually because the update script does not support MSVC-mangled names.
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-pc-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=WINDOWS
// RUN: %clang_cc1 -std=c++20 -triple=armv7a-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-LE
// RUN: %clang_cc1 -std=c++20 -triple=armebv7a-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-BE
-// RUN: %clang_cc1 -std=c++20 -triple=aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-LE
-// RUN: %clang_cc1 -std=c++20 -triple=aarch64_be-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM-BE
+// RUN: %clang_cc1 -std=c++20 -triple=aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=AARCH64-LE
+// RUN: %clang_cc1 -std=c++20 -triple=aarch64_be-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefix=AARCH64-BE
struct Empty {};
@@ -18,7 +19,6 @@ struct Empty {};
// LINUX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
// LINUX-NEXT: store i8 0, ptr [[TMP1]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testEmpty@@YAXPEAUEmpty@@@Z"(ptr noundef %e) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %e.addr = alloca ptr, align 8
@@ -28,6 +28,46 @@ struct Empty {};
// WINDOWS-NEXT: store i8 0, ptr %1, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z9testEmptyP5Empty(
+// ARM-LE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z9testEmptyP5Empty(
+// ARM-BE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z9testEmptyP5Empty(
+// AARCH64-LE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z9testEmptyP5Empty(
+// AARCH64-BE-SAME: ptr noundef [[E:%.*]]) #[[ATTR0:[0-9]+]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testEmpty(Empty *e) {
// This should clear the one byte that Empty occupies.
__builtin_clear_padding(e);
@@ -48,6 +88,37 @@ void testEmpty(Empty *e) {
// WINDOWS-NEXT: store ptr %i, ptr %i.addr, align 8
// WINDOWS-NEXT: %0 = load ptr, ptr %i.addr, align 8
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z22testPrimitiveNoPaddingPi(
+// ARM-LE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z22testPrimitiveNoPaddingPi(
+// ARM-BE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z22testPrimitiveNoPaddingPi(
+// AARCH64-LE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z22testPrimitiveNoPaddingPi(
+// AARCH64-BE-SAME: ptr noundef [[I:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[I_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
//
void testPrimitiveNoPadding(int *i) {
// This should not clear any padding, since int has no padding.
@@ -81,6 +152,37 @@ void testPrimitiveNoPadding(int *i) {
// WINDOWS-NEXT: store ptr %ld, ptr %ld.addr, align 8
// WINDOWS-NEXT: %0 = load ptr, ptr %ld.addr, align 8
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z23testPrimitiveLongDoublePe(
+// ARM-LE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z23testPrimitiveLongDoublePe(
+// ARM-BE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z23testPrimitiveLongDoublePe(
+// AARCH64-LE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z23testPrimitiveLongDoublePe(
+// AARCH64-BE-SAME: ptr noundef [[LD:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[LD_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[LD]], ptr [[LD_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LD_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
//
void testPrimitiveLongDouble(long double *ld) {
// padding [10, 15] on x86
@@ -104,7 +206,6 @@ void testPrimitiveLongDouble(long double *ld) {
// LINUX-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
// LINUX-NEXT: store i8 0, ptr [[TMP6]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testBitInt@@YAXPEAU?$_BitInt@$0GB@@__clang@@@Z"(ptr noundef %bi) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %bi.addr = alloca ptr, align 8
@@ -123,82 +224,200 @@ void testPrimitiveLongDouble(long double *ld) {
// WINDOWS-NEXT: ret void
//
// ARM-LE-LABEL: define dso_local void @_Z10testBitIntPDB97_(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE12:%.*]] = getelementptr i8, ptr [[OBJ]], i32 12
-// ARM-LE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-LE-NEXT: store i8 [[MASKED]], ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[BYTE13:%.*]] = getelementptr i8, ptr [[OBJ]], i32 13
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE13]], align 1
-// ARM-LE-NEXT: [[BYTE14:%.*]] = getelementptr i8, ptr [[OBJ]], i32 14
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE14]], align 2
-// ARM-LE-NEXT: [[BYTE15:%.*]] = getelementptr i8, ptr [[OBJ]], i32 15
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE15]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @_Z10testBitIntPDB97_(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE1:%.*]] = getelementptr i8, ptr [[OBJ]], i32 1
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE1]], align 1
-// ARM-BE-NEXT: [[BYTE2:%.*]] = getelementptr i8, ptr [[OBJ]], i32 2
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE2]], align 2
-// ARM-BE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-BE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-BE-NEXT: store i8 [[MASKED]], ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z10testBitIntPDB97_(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z10testBitIntPDB97_(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testBitInt(_BitInt(97) *bi) {
// Storage is widened to 128 bits; clear bits [97, 128).
__builtin_clear_padding(bi);
}
+//
// ARM-LE-LABEL: define dso_local void @_Z21testBitIntByteAlignedPDB24_(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE3]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @_Z21testBitIntByteAlignedPDB24_(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align 4
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z21testBitIntByteAlignedPDB24_(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z21testBitIntByteAlignedPDB24_(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: ret void
//
void testBitIntByteAligned(_BitInt(24) *bi) {
// Storage is widened to 32 bits; clear the leading or trailing byte.
__builtin_clear_padding(bi);
}
+//
// ARM-LE-LABEL: define dso_local void @_Z18testVolatileBitIntPVDB97_(
-// ARM-LE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-LE-NEXT: [[BYTE12:%.*]] = getelementptr i8, ptr [[OBJ]], i32 12
-// ARM-LE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-LE-NEXT: store i8 [[MASKED]], ptr [[BYTE12]], align 4
-// ARM-LE-NEXT: [[BYTE13:%.*]] = getelementptr i8, ptr [[OBJ]], i32 13
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE13]], align 1
-// ARM-LE-NEXT: [[BYTE14:%.*]] = getelementptr i8, ptr [[OBJ]], i32 14
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE14]], align 2
-// ARM-LE-NEXT: [[BYTE15:%.*]] = getelementptr i8, ptr [[OBJ]], i32 15
-// ARM-LE-NEXT: store i8 0, ptr [[BYTE15]], align 1
-// ARM-LE-NEXT: ret void
+// ARM-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
//
// ARM-BE-LABEL: define dso_local void @_Z18testVolatileBitIntPVDB97_(
-// ARM-BE: [[OBJ:%.*]] = load ptr, ptr {{.*}}, align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE0:%.*]] = getelementptr i8, ptr [[OBJ]], i32 0
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE0]], align {{[0-9]+}}
-// ARM-BE-NEXT: [[BYTE1:%.*]] = getelementptr i8, ptr [[OBJ]], i32 1
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE1]], align 1
-// ARM-BE-NEXT: [[BYTE2:%.*]] = getelementptr i8, ptr [[OBJ]], i32 2
-// ARM-BE-NEXT: store i8 0, ptr [[BYTE2]], align 2
-// ARM-BE-NEXT: [[BYTE3:%.*]] = getelementptr i8, ptr [[OBJ]], i32 3
-// ARM-BE-NEXT: [[VALUE:%.*]] = load i8, ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: [[MASKED:%.*]] = and i8 [[VALUE]], 1
-// ARM-BE-NEXT: store i8 [[MASKED]], ptr [[BYTE3]], align 1
-// ARM-BE-NEXT: ret void
+// ARM-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z18testVolatileBitIntPVDB97_(
+// AARCH64-LE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z18testVolatileBitIntPVDB97_(
+// AARCH64-BE-SAME: ptr noundef [[BI:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BI_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BI]], ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BI_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testVolatileBitInt(volatile _BitInt(97) *bi) {
__builtin_clear_padding(bi);
@@ -243,6 +462,37 @@ void testVolatileBitInt(volatile _BitInt(97) *bi) {
// WINDOWS-NEXT: store ptr %c, ptr %c.addr, align 8
// WINDOWS-NEXT: %0 = load ptr, ptr %c.addr, align 8
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z30testPrimitiveComplexLongDoublePCe(
+// ARM-LE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z30testPrimitiveComplexLongDoublePCe(
+// ARM-BE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z30testPrimitiveComplexLongDoublePCe(
+// AARCH64-LE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z30testPrimitiveComplexLongDoublePCe(
+// AARCH64-BE-SAME: ptr noundef [[C:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
//
void testPrimitiveComplexLongDouble(_Complex long double *c) {
// padding [10, 15] and [26, 31] on x86
@@ -261,7 +511,6 @@ union U1 {
// LINUX-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
// LINUX-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testUnionDifferentLength@@YAXPEATU1@@@Z"(ptr noundef %u) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %u.addr = alloca ptr, align 8
@@ -269,6 +518,38 @@ union U1 {
// WINDOWS-NEXT: %0 = load ptr, ptr %u.addr, align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z24testUnionDifferentLengthP2U1(
+// ARM-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z24testUnionDifferentLengthP2U1(
+// ARM-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z24testUnionDifferentLengthP2U1(
+// AARCH64-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z24testUnionDifferentLengthP2U1(
+// AARCH64-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: ret void
+//
void testUnionDifferentLength(U1 *u) {
// This should not clear the object representation bits of the non-active member.
__builtin_clear_padding(u);
@@ -305,7 +586,6 @@ union U2 {
// LINUX-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
// LINUX-NEXT: store i8 0, ptr [[TMP7]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testUnionTailPaddingOfLongestMember@@YAXPEATU2@@@Z"(ptr noundef %u) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %u.addr = alloca ptr, align 8
@@ -327,6 +607,94 @@ union U2 {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z35testUnionTailPaddingOfLongestMemberP2U2(
+// ARM-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z35testUnionTailPaddingOfLongestMemberP2U2(
+// ARM-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z35testUnionTailPaddingOfLongestMemberP2U2(
+// AARCH64-LE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z35testUnionTailPaddingOfLongestMemberP2U2(
+// AARCH64-BE-SAME: ptr noundef [[U:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[U_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[U]], ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[U_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnionTailPaddingOfLongestMember(U2 *u) {
// This should clear the tail padding of the longest member.
// [1 - 7]
@@ -397,6 +765,93 @@ struct alignas(4) Baz : Foo {
// WINDOWS-NEXT: %7 = getelementptr i8, ptr %0, i32 11
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z33testStructPaddingInBetweenMembersP3Baz(
+// ARM-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z33testStructPaddingInBetweenMembersP3Baz(
+// ARM-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z33testStructPaddingInBetweenMembersP3Baz(
+// AARCH64-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z33testStructPaddingInBetweenMembersP3Baz(
+// AARCH64-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testStructPaddingInBetweenMembers(Baz *baz) {
// this should clear all the padding in between various members
@@ -424,7 +879,6 @@ void testStructPaddingInBetweenMembers(Baz *baz) {
// LINUX-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
// LINUX-NEXT: store i8 0, ptr [[TMP7]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testStructVolatile@@YAXPECUBaz@@@Z"(ptr noundef %baz) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %baz.addr = alloca ptr, align 8
@@ -446,6 +900,94 @@ void testStructPaddingInBetweenMembers(Baz *baz) {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z18testStructVolatilePV3Baz(
+// ARM-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z18testStructVolatilePV3Baz(
+// ARM-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z18testStructVolatilePV3Baz(
+// AARCH64-LE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z18testStructVolatilePV3Baz(
+// AARCH64-BE-SAME: ptr noundef [[BAZ:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAZ_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAZ]], ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAZ_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testStructVolatile(volatile Baz *baz) {
// this should clear all the padding in between various members
__builtin_clear_padding(baz);
@@ -491,6 +1033,53 @@ class S2 {
// WINDOWS-NEXT: %6 = getelementptr i8, ptr %0, i32 11
// WINDOWS-NEXT: store i8 0, ptr %6, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z19testNoUniqueAddressP2S2(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z19testNoUniqueAddressP2S2(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z19testNoUniqueAddressP2S2(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z19testNoUniqueAddressP2S2(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testNoUniqueAddress(S2 *s) {
// "x [0-3]", "c" , "b", PAD [6-7]
@@ -551,7 +1140,6 @@ struct S3 {
// LINUX-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
// LINUX-NEXT: store i8 0, ptr [[TMP21]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testStructWithLongDouble@@YAXPEAUS3@@@Z"(ptr noundef %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.addr = alloca ptr, align 8
@@ -573,6 +1161,126 @@ struct S3 {
// WINDOWS-NEXT: store i8 0, ptr %7, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z24testStructWithLongDoubleP2S3(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 10
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z24testStructWithLongDoubleP2S3(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 10
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z24testStructWithLongDoubleP2S3(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 17
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 18
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 19
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 20
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 21
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 8
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 4
+// AARCH64-LE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP13]], align 1
+// AARCH64-LE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP14]], align 2
+// AARCH64-LE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z24testStructWithLongDoubleP2S3(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 17
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 18
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 19
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 20
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 21
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 8
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP13]], align 1
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP14]], align 2
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testStructWithLongDouble(S3 *s) {
// "long double data[0-9]", PAD [10-15], "b", PAD [17-31]
__builtin_clear_padding(s);
@@ -611,6 +1319,61 @@ struct S4 : Empty, B {
// WINDOWS-NEXT: %3 = getelementptr i8, ptr %0, i32 7
// WINDOWS-NEXT: store i8 0, ptr %3, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z23testStructWithEmptyBaseP2S4(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z23testStructWithEmptyBaseP2S4(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z23testStructWithEmptyBaseP2S4(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z23testStructWithEmptyBaseP2S4(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testStructWithEmptyBase(S4 *s) {
// "i" [0-3], "b" [4], PAD [5-7]
@@ -645,7 +1408,6 @@ struct S5 : B1, B2 {
// LINUX-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
// LINUX-NEXT: store i8 0, ptr [[TMP6]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testPaddingBetweenBases@@YAXPEAUS5@@@Z"(ptr noundef %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.addr = alloca ptr, align 8
@@ -665,6 +1427,86 @@ struct S5 : B1, B2 {
// WINDOWS-NEXT: store i8 0, ptr %6, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z23testPaddingBetweenBasesP2S5(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z23testPaddingBetweenBasesP2S5(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z23testPaddingBetweenBasesP2S5(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z23testPaddingBetweenBasesP2S5(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testPaddingBetweenBases(S5 *s) {
// "c1" [0], PAD [1-3] , "c2" [4], PAD [5-7]
__builtin_clear_padding(s);
@@ -716,6 +1558,77 @@ struct S6 : B3, B4 {
// WINDOWS-NEXT: %5 = getelementptr i8, ptr %0, i32 7
// WINDOWS-NEXT: store i8 0, ptr %5, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z24testPaddingAfterLastBaseP2S6(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z24testPaddingAfterLastBaseP2S6(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z24testPaddingAfterLastBaseP2S6(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z24testPaddingAfterLastBaseP2S6(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testPaddingAfterLastBase(S6 *s) {
// "c1"[0], "c2"[1], PAD [2-3], "c3" [4], PAD [5-7]
@@ -725,7 +1638,9 @@ void testPaddingAfterLastBase(S6 *s) {
struct VirtualBase {
unsigned int x;
+//
virtual int call() { return x; };
+//
virtual ~VirtualBase() = default;
};
@@ -734,6 +1649,7 @@ struct NonVirtualBase {
};
struct S7 : VirtualBase, NonVirtualBase {
+//
virtual int call() override { return 5; }
bool z;
};
@@ -775,6 +1691,49 @@ struct S7 : VirtualBase, NonVirtualBase {
// WINDOWS-NEXT: store i8 0, ptr %9, align 1
// WINDOWS-NEXT: call void @"??1S7@@UEAA at XZ"(ptr noundef nonnull align 8 dead_on_return(24) dereferenceable(24) %s) #1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z10testVtable2S7(
+// ARM-LE-SAME: ptr nofree noundef align 4 dereferenceable(12) [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z10testVtable2S7(
+// ARM-BE-SAME: ptr nofree noundef align 4 dereferenceable(12) [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z10testVtable2S7(
+// AARCH64-LE-SAME: ptr nofree noundef align 8 dereferenceable(16) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z10testVtable2S7(
+// AARCH64-BE-SAME: ptr nofree noundef align 8 dereferenceable(16) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testVtable(S7 s) {
// "vtable ptr" [0-7], "x" [8-11], "y" [12], "z" [13], PAD [14-15]
@@ -783,18 +1742,21 @@ void testVtable(S7 s) {
struct VirtualBase1 {
unsigned int x1;
+//
virtual int call1() { return x1; };
virtual ~VirtualBase1() = default;
};
struct VirtualBase2 {
unsigned int x2;
+//
virtual int call2() { return x2; };
virtual ~VirtualBase2() = default;
};
struct VirtualBase3 {
unsigned int x3;
+//
virtual int call3() { return x3; };
virtual ~VirtualBase3() = default;
};
@@ -803,6 +1765,7 @@ struct NonVirtualBase1 {
char y;
};
struct S8 : VirtualBase1, VirtualBase2, NonVirtualBase1, VirtualBase3 {
+//
virtual int call1() override { return 5; }
bool z;
};
@@ -833,7 +1796,6 @@ struct S8 : VirtualBase1, VirtualBase2, NonVirtualBase1, VirtualBase3 {
// LINUX-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 47
// LINUX-NEXT: store i8 0, ptr [[TMP9]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testMultipleBasesVtable@@YAXUS8@@@Z"(ptr nofree noundef align 8 dead_on_return dereferenceable(56) %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.indirect_addr = alloca ptr, align 8
@@ -877,6 +1839,98 @@ struct S8 : VirtualBase1, VirtualBase2, NonVirtualBase1, VirtualBase3 {
// WINDOWS-NEXT: call void @"??1S8@@UEAA at XZ"(ptr noundef nonnull align 8 dead_on_return(56) dereferenceable(56) %s) #1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z23testMultipleBasesVtable2S8(
+// ARM-LE-SAME: ptr nofree noundef align 4 dereferenceable(32) [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 17
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 18
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 19
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z23testMultipleBasesVtable2S8(
+// ARM-BE-SAME: ptr nofree noundef align 4 dereferenceable(32) [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 17
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 18
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 19
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z23testMultipleBasesVtable2S8(
+// AARCH64-LE-SAME: ptr nofree noundef align 8 dereferenceable(48) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 4
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 45
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 46
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 2
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 47
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z23testMultipleBasesVtable2S8(
+// AARCH64-BE-SAME: ptr nofree noundef align 8 dereferenceable(48) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 12
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 4
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 45
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 46
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 2
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 47
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testMultipleBasesVtable(S8 s) {
// "vtable ptr" [0-7], "x1" [8-11], PAD "[12-15]",
// "vtable ptr" [16-23], "x2" [24-27], "y" [28], PAD "[29-31]",
@@ -886,18 +1940,21 @@ void testMultipleBasesVtable(S8 s) {
struct VirtualChain1 {
unsigned int x1;
+//
virtual int call1() { return x1; };
virtual ~VirtualChain1() = default;
};
struct VirtualChain2 : VirtualChain1 {
unsigned int x2;
+//
virtual int call2() { return x2; };
virtual ~VirtualChain2() = default;
};
struct VirtualChain3 : VirtualChain2 {
unsigned int x3;
+//
virtual int call3() { return x3; };
virtual ~VirtualChain3() = default;
};
@@ -963,6 +2020,49 @@ struct S9 : NonVirtualBase2, VirtualChain3 {
// WINDOWS-NEXT: store i8 0, ptr %17, align 1
// WINDOWS-NEXT: call void @"??1S9@@UEAA at XZ"(ptr noundef nonnull align 8 dead_on_return(40) dereferenceable(40) %s) #1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z16testVirtualChain2S9(
+// ARM-LE-SAME: ptr nofree noundef align 4 dereferenceable(20) [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 18
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 19
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z16testVirtualChain2S9(
+// ARM-BE-SAME: ptr nofree noundef align 4 dereferenceable(20) [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 18
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 19
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z16testVirtualChain2S9(
+// AARCH64-LE-SAME: ptr nofree noundef align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z16testVirtualChain2S9(
+// AARCH64-BE-SAME: ptr nofree noundef align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 2
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testVirtualChain(S9 s) {
// This should clear the padding after the bool z.
@@ -1014,7 +2114,6 @@ struct S10 : D1, D2 {
// LINUX-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 39
// LINUX-NEXT: store i8 0, ptr [[TMP8]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testVirtualInheritance@@YAXUS10@@@Z"(ptr nofree noundef align 8 dead_on_return dereferenceable(48) %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.indirect_addr = alloca ptr, align 8
@@ -1055,6 +2154,90 @@ struct S10 : D1, D2 {
// WINDOWS-NEXT: store i8 0, ptr %16, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z22testVirtualInheritance3S10(
+// ARM-LE-SAME: ptr nofree noundef align 4 dead_on_return dereferenceable(28) [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z22testVirtualInheritance3S10(
+// ARM-BE-SAME: ptr nofree noundef align 4 dead_on_return dereferenceable(28) [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z22testVirtualInheritance3S10(
+// AARCH64-LE-SAME: ptr nofree noundef align 8 dead_on_return dereferenceable(40) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 36
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 37
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 38
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 39
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z22testVirtualInheritance3S10(
+// AARCH64-BE-SAME: ptr nofree noundef align 8 dead_on_return dereferenceable(40) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 36
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 37
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 38
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 39
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testVirtualInheritance(S10 s) {
// note derived member placed before the virtual base
// "vtable ptr" [0-7], "d1" [8-11], "b1" [12], PAD [13-15],
@@ -1110,6 +2293,73 @@ struct S10_2 : virtual Base {
// WINDOWS-NEXT: store i8 0, ptr %6, align 1
// WINDOWS-NEXT: call void @"??_DS10_2@@QEAAXXZ"(ptr noundef nonnull align 8 dereferenceable(24) %s) #1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z40testVirtualInheritanceAndVirtualFunction5S10_2(
+// ARM-LE-SAME: ptr nofree noundef align 4 dereferenceable(16) [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 9
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z40testVirtualInheritanceAndVirtualFunction5S10_2(
+// ARM-BE-SAME: ptr nofree noundef align 4 dereferenceable(16) [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 9
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 10
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 11
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z40testVirtualInheritanceAndVirtualFunction5S10_2(
+// AARCH64-LE-SAME: ptr nofree noundef align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 20
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z40testVirtualInheritanceAndVirtualFunction5S10_2(
+// AARCH64-BE-SAME: ptr nofree noundef align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 20
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testVirtualInheritanceAndVirtualFunction(S10_2 s) {
__builtin_clear_padding(&s);
@@ -1145,6 +2395,53 @@ struct S11 {
// WINDOWS-NEXT: %3 = and i8 %2, 31
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z13testBitFieldsP3S11(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z13testBitFieldsP3S11(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -8
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z13testBitFieldsP3S11(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 31
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z13testBitFieldsP3S11(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -8
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testBitFields(S11 *s) {
// "b1" [0-2], "b2" [3-4], PAD [5-7], "b3" [8-13], "b4" [14-15]
@@ -1152,6 +2449,671 @@ void testBitFields(S11 *s) {
__builtin_clear_padding(s);
}
+struct VolatileBitfield {
+ volatile unsigned char a : 5;
+ int b : 7;
+ volatile int c : 27;
+};
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z21testVolatileBitfieldsP16VolatileBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// ARM-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z21testVolatileBitfieldsP16VolatileBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// ARM-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z21testVolatileBitfieldsP16VolatileBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// AARCH64-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z21testVolatileBitfieldsP16VolatileBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileBitfields(struct VolatileBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z35testVolatileBitfieldsVolatileStructPV16VolatileBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// ARM-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z35testVolatileBitfieldsVolatileStructPV16VolatileBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// ARM-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z35testVolatileBitfieldsVolatileStructPV16VolatileBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], 7
+// AARCH64-LE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z35testVolatileBitfieldsVolatileStructPV16VolatileBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = and i8 [[TMP7]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP8]], ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileBitfieldsVolatileStruct(volatile struct VolatileBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+#ifndef _WIN32
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wbitfield-width"
+
+struct OversizedBitfield {
+ unsigned char a : 10;
+ int b;
+ int c : 35;
+};
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z21testOversizedBitfieldP17OversizedBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z21testOversizedBitfieldP17OversizedBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z21testOversizedBitfieldP17OversizedBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z21testOversizedBitfieldP17OversizedBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testOversizedBitfield(struct OversizedBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z35testOversizedBitfieldVolatileStructPV17OversizedBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z35testOversizedBitfieldVolatileStructPV17OversizedBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z35testOversizedBitfieldVolatileStructPV17OversizedBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z35testOversizedBitfieldVolatileStructPV17OversizedBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testOversizedBitfieldVolatileStruct(volatile struct OversizedBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+struct VolatileOversizedBitfield {
+ volatile unsigned char a : 10;
+ int b;
+ volatile int c : 35;
+};
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z29testVolatileOversizedBitfieldP25VolatileOversizedBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z29testVolatileOversizedBitfieldP25VolatileOversizedBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z29testVolatileOversizedBitfieldP25VolatileOversizedBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z29testVolatileOversizedBitfieldP25VolatileOversizedBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileOversizedBitfield(struct VolatileOversizedBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+//
+// ARM-LE-LABEL: define dso_local void @_Z43testVolatileOversizedBitfieldVolatileStructPV25VolatileOversizedBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z43testVolatileOversizedBitfieldVolatileStructPV25VolatileOversizedBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z43testVolatileOversizedBitfieldVolatileStructPV25VolatileOversizedBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 4
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 2
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z43testVolatileOversizedBitfieldVolatileStructPV25VolatileOversizedBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31
+// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32
+// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2
+// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1
+// AARCH64-BE-NEXT: ret void
+//
+void testVolatileOversizedBitfieldVolatileStruct(volatile struct VolatileOversizedBitfield *s) {
+ __builtin_clear_padding(s);
+}
+
+#pragma clang diagnostic pop
+
+#endif // _WIN32
+
// LINUX-LABEL: define dso_local void @_Z18testArrayNoPaddingv(
// LINUX-SAME: ) #[[ATTR0]] {
@@ -1163,6 +3125,29 @@ void testBitFields(S11 *s) {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %i = alloca [4 x i32], align 4
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z18testArrayNoPaddingv(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z18testArrayNoPaddingv(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z18testArrayNoPaddingv(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z18testArrayNoPaddingv(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[I:%.*]] = alloca [4 x i32], align 4
+// AARCH64-BE-NEXT: ret void
//
void testArrayNoPadding() {
int i[4];
@@ -1199,12 +3184,35 @@ void testArrayNoPadding() {
// LINUX-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[LD]], i32 31
// LINUX-NEXT: store i8 0, ptr [[TMP11]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testArrayLongDouble@@YAXXZ"() #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %ld = alloca [2 x double], align 8
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z19testArrayLongDoublev(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[LD:%.*]] = alloca [2 x double], align 8
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z19testArrayLongDoublev(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[LD:%.*]] = alloca [2 x double], align 8
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z19testArrayLongDoublev(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[LD:%.*]] = alloca [2 x fp128], align 16
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z19testArrayLongDoublev(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[LD:%.*]] = alloca [2 x fp128], align 16
+// AARCH64-BE-NEXT: ret void
+//
void testArrayLongDouble() {
// long double 0, [0-9] PAD [10-15]
// long double 1, [16-25] PAD [26-31]
@@ -1241,7 +3249,6 @@ void testArrayLongDouble() {
// LINUX-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
// LINUX-NEXT: store i8 0, ptr [[TMP11]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testArrayOfStruct@@YAXXZ"() #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s = alloca [2 x %struct.S.0], align 4
@@ -1271,6 +3278,126 @@ void testArrayLongDouble() {
// WINDOWS-NEXT: store i8 0, ptr %11, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z17testArrayOfStructv(
+// ARM-LE-SAME: ) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_0:%.*]]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// ARM-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// ARM-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z17testArrayOfStructv(
+// ARM-BE-SAME: ) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_0:%.*]]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// ARM-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// ARM-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// ARM-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// ARM-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// ARM-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z17testArrayOfStructv(
+// AARCH64-LE-SAME: ) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_0:%.*]]], align 4
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z17testArrayOfStructv(
+// AARCH64-BE-SAME: ) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S:%.*]] = alloca [2 x [[STRUCT_S_0:%.*]]], align 4
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[S]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[S]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 2
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[S]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[S]], i32 21
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[S]], i32 22
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[S]], i32 23
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S]], i32 29
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 1
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[S]], i32 30
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 2
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[S]], i32 31
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testArrayOfStruct() {
struct S {
int i1;
@@ -1326,6 +3453,69 @@ struct ArrOfStructsWithPadding {
// WINDOWS-NEXT: %4 = getelementptr i8, ptr %0, i32 7
// WINDOWS-NEXT: store i8 0, ptr %4, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z27testArrOfStructsWithPaddingP23ArrOfStructsWithPadding(
+// ARM-LE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z27testArrOfStructsWithPaddingP23ArrOfStructsWithPadding(
+// ARM-BE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z27testArrOfStructsWithPaddingP23ArrOfStructsWithPadding(
+// AARCH64-LE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z27testArrOfStructsWithPaddingP23ArrOfStructsWithPadding(
+// AARCH64-BE-SAME: ptr noundef [[ARR:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[ARR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[ARR]], ptr [[ARR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testArrOfStructsWithPadding(ArrOfStructsWithPadding *arr) {
__builtin_clear_padding(arr);
@@ -1363,6 +3553,61 @@ struct S12 {
// WINDOWS-NEXT: %3 = getelementptr i8, ptr %0, i32 7
// WINDOWS-NEXT: store i8 0, ptr %3, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z18testTemplateStructP3S12IiE(
+// ARM-LE-SAME: ptr noundef [[S12:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S12_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S12]], ptr [[S12_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S12_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z18testTemplateStructP3S12IiE(
+// ARM-BE-SAME: ptr noundef [[S12:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S12_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S12]], ptr [[S12_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S12_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z18testTemplateStructP3S12IiE(
+// AARCH64-LE-SAME: ptr noundef [[S12:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S12_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S12]], ptr [[S12_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S12_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z18testTemplateStructP3S12IiE(
+// AARCH64-BE-SAME: ptr noundef [[S12:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S12_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S12]], ptr [[S12_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S12_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testTemplateStruct(S12<int>* s12) {
__builtin_clear_padding(s12);
@@ -1379,7 +3624,6 @@ void testTemplateStruct(S12<int>* s12) {
// LINUX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
// LINUX-NEXT: store i8 0, ptr [[TMP2]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testAtomic@@YAXPEAU?$_Atomic at UBar@@@__clang@@@Z"(ptr noundef %bar) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %bar.addr = alloca ptr, align 8
@@ -1391,6 +3635,54 @@ void testTemplateStruct(S12<int>* s12) {
// WINDOWS-NEXT: store i8 0, ptr %2, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z10testAtomicPU7_Atomic3Bar(
+// ARM-LE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z10testAtomicPU7_Atomic3Bar(
+// ARM-BE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z10testAtomicPU7_Atomic3Bar(
+// AARCH64-LE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z10testAtomicPU7_Atomic3Bar(
+// AARCH64-BE-SAME: ptr noundef [[BAR:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[BAR_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[BAR]], ptr [[BAR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[BAR_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAtomic(_Atomic(Bar)* bar) {
__builtin_clear_padding(bar);
}
@@ -1400,8 +3692,11 @@ struct NonTriviallyCopyable {
int i;
char c;
+//
NonTriviallyCopyable(){}
+//
NonTriviallyCopyable(const NonTriviallyCopyable&) {}
+//
~NonTriviallyCopyable() {}
};
@@ -1430,6 +3725,57 @@ struct NonTriviallyCopyable {
// WINDOWS-NEXT: store i8 0, ptr %2, align 1
// WINDOWS-NEXT: call void @"??1NonTriviallyCopyable@@QEAA at XZ"(ptr noundef nonnull align 4 dead_on_return(8) dereferenceable(8) %ntc) #1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z24testNonTriviallyCopyable20NonTriviallyCopyable(
+// ARM-LE-SAME: ptr nofree noundef align 4 dereferenceable(8) [[NTC:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[NTC_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[NTC]], ptr [[NTC_INDIRECT_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[NTC]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[NTC]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[NTC]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z24testNonTriviallyCopyable20NonTriviallyCopyable(
+// ARM-BE-SAME: ptr nofree noundef align 4 dereferenceable(8) [[NTC:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[NTC_INDIRECT_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[NTC]], ptr [[NTC_INDIRECT_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[NTC]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[NTC]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[NTC]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z24testNonTriviallyCopyable20NonTriviallyCopyable(
+// AARCH64-LE-SAME: ptr nofree noundef align 4 dereferenceable(8) [[NTC:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[NTC_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[NTC]], ptr [[NTC_INDIRECT_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[NTC]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[NTC]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[NTC]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z24testNonTriviallyCopyable20NonTriviallyCopyable(
+// AARCH64-BE-SAME: ptr nofree noundef align 4 dereferenceable(8) [[NTC:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[NTC_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[NTC]], ptr [[NTC_INDIRECT_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[NTC]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP0]], align 1
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[NTC]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[NTC]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testNonTriviallyCopyable(NonTriviallyCopyable ntc) {
__builtin_clear_padding(&ntc);
@@ -1453,7 +3799,6 @@ typedef long double LongDouble3Vec __attribute__((ext_vector_type(3)));
// LINUX-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
// LINUX-NEXT: store i8 0, ptr [[TMP4]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testAttributedType@@YAXPEAT?$__vector at M$02 at __clang@@@Z"(ptr noundef %v) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %v.addr = alloca ptr, align 8
@@ -1469,6 +3814,70 @@ typedef long double LongDouble3Vec __attribute__((ext_vector_type(3)));
// WINDOWS-NEXT: store i8 0, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z18testAttributedTypePDv3_f(
+// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z18testAttributedTypePDv3_f(
+// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z18testAttributedTypePDv3_f(
+// AARCH64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z18testAttributedTypePDv3_f(
+// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAttributedType(Float3Vec* v) {
__builtin_clear_padding(v);
}
@@ -1548,7 +3957,6 @@ void testAttributedType(Float3Vec* v) {
// LINUX-NEXT: [[TMP34:%.*]] = getelementptr i8, ptr [[TMP0]], i32 63
// LINUX-NEXT: store i8 0, ptr [[TMP34]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testAttributedLongDoubleType@@YAXPEAT?$__vector at O$02 at __clang@@@Z"(ptr noundef %v) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %v.addr = alloca ptr, align 8
@@ -1572,6 +3980,134 @@ void testAttributedType(Float3Vec* v) {
// WINDOWS-NEXT: store i8 0, ptr %8, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z28testAttributedLongDoubleTypePDv3_e(
+// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// ARM-LE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// ARM-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// ARM-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// ARM-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// ARM-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z28testAttributedLongDoubleTypePDv3_e(
+// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 24
+// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 8
+// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 25
+// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 26
+// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 27
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 28
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 29
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 30
+// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 31
+// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z28testAttributedLongDoubleTypePDv3_e(
+// AARCH64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 49
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 50
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 51
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 52
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 53
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 54
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 55
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 56
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP9]], align 8
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 57
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 58
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 59
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-LE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 60
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP13]], align 4
+// AARCH64-LE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 61
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP14]], align 1
+// AARCH64-LE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 62
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP15]], align 2
+// AARCH64-LE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 63
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP16]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z28testAttributedLongDoubleTypePDv3_e(
+// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 16
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 49
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 50
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 51
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 52
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 4
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 53
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 54
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 55
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 56
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP9]], align 8
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 57
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 58
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 59
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-BE-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[TMP0]], i32 60
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP13]], align 4
+// AARCH64-BE-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[TMP0]], i32 61
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP14]], align 1
+// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 62
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 2
+// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 63
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testAttributedLongDoubleType(LongDouble3Vec *v) {
// long double elements occupy [0-9], [16-25], [32-41] on x86.
__builtin_clear_padding(v);
@@ -1605,6 +4141,53 @@ struct UnnamedBitfieldSingleBit {
// WINDOWS-NEXT: %3 = and i8 %2, -9
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z28testUnnamedBitfieldSingleBitP24UnnamedBitfieldSingleBit(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -9
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z28testUnnamedBitfieldSingleBitP24UnnamedBitfieldSingleBit(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -17
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z28testUnnamedBitfieldSingleBitP24UnnamedBitfieldSingleBit(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -9
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z28testUnnamedBitfieldSingleBitP24UnnamedBitfieldSingleBit(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -17
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testUnnamedBitfieldSingleBit(struct UnnamedBitfieldSingleBit *s) {
// byte 0: a[bits 0-2], unnamed[bit 3], b[bits 4-7]
@@ -1641,6 +4224,53 @@ struct UnnamedBitfieldMiddle {
// WINDOWS-NEXT: %3 = and i8 %2, -25
// WINDOWS-NEXT: store i8 %3, ptr %1, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z25testUnnamedBitfieldMiddleP21UnnamedBitfieldMiddle(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z25testUnnamedBitfieldMiddleP21UnnamedBitfieldMiddle(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z25testUnnamedBitfieldMiddleP21UnnamedBitfieldMiddle(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z25testUnnamedBitfieldMiddleP21UnnamedBitfieldMiddle(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -25
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testUnnamedBitfieldMiddle(struct UnnamedBitfieldMiddle *s) {
// byte 0: a[0-2], unnamed[3-4], b[5-7]
@@ -1670,7 +4300,6 @@ struct UnnamedBitfieldSurrounding {
// LINUX-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
// LINUX-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testUnnamedBitfieldSurrounding@@YAXPEAUUnnamedBitfieldSurrounding@@@Z"(ptr noundef %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.addr = alloca ptr, align 8
@@ -1686,6 +4315,70 @@ struct UnnamedBitfieldSurrounding {
// WINDOWS-NEXT: store i8 %6, ptr %4, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z30testUnnamedBitfieldSurroundingP26UnnamedBitfieldSurrounding(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// ARM-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z30testUnnamedBitfieldSurroundingP26UnnamedBitfieldSurrounding(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z30testUnnamedBitfieldSurroundingP26UnnamedBitfieldSurrounding(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// AARCH64-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z30testUnnamedBitfieldSurroundingP26UnnamedBitfieldSurrounding(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -4
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedBitfieldSurrounding(struct UnnamedBitfieldSurrounding *s) {
// byte 0: unnamed[0-1], a[2-5], unnamed[6-7]
// bits 0-1 and 6-7 must be cleared
@@ -1728,7 +4421,6 @@ struct UnnamedZeroWidthBitfield {
// LINUX-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
// LINUX-NEXT: store i8 0, ptr [[TMP12]], align 1
// LINUX-NEXT: ret void
-//
// WINDOWS-LABEL: define dso_local void @"?testUnnamedZeroWidthBitfield@@YAXPEAUUnnamedZeroWidthBitfield@@@Z"(ptr noundef %s) #0 {
// WINDOWS-NEXT: entry:
// WINDOWS-NEXT: %s.addr = alloca ptr, align 8
@@ -1756,6 +4448,118 @@ struct UnnamedZeroWidthBitfield {
// WINDOWS-NEXT: store i8 0, ptr %12, align 1
// WINDOWS-NEXT: ret void
//
+// ARM-LE-LABEL: define dso_local void @_Z28testUnnamedZeroWidthBitfieldP24UnnamedZeroWidthBitfield(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-LE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// ARM-LE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15
+// ARM-LE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// ARM-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// ARM-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// ARM-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z28testUnnamedZeroWidthBitfieldP24UnnamedZeroWidthBitfield(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// ARM-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// ARM-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], -16
+// ARM-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// ARM-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// ARM-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// ARM-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// ARM-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// ARM-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z28testUnnamedZeroWidthBitfieldP24UnnamedZeroWidthBitfield(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-LE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-LE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// AARCH64-LE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// AARCH64-LE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-LE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-LE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-LE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z28testUnnamedZeroWidthBitfieldP24UnnamedZeroWidthBitfield(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1
+// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4
+// AARCH64-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 4
+// AARCH64-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 4
+// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP10]], align 1
+// AARCH64-BE-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP11]], align 2
+// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7
+// AARCH64-BE-NEXT: store i8 0, ptr [[TMP12]], align 1
+// AARCH64-BE-NEXT: ret void
+//
void testUnnamedZeroWidthBitfield(struct UnnamedZeroWidthBitfield *s) {
// byte 0: a[0-3], unnamed[4-7]
// bytes 1-3: struct padding
@@ -1809,6 +4613,69 @@ struct UnnamedBitfieldMultiByte {
// WINDOWS-NEXT: %6 = and i8 %5, -16
// WINDOWS-NEXT: store i8 %6, ptr %4, align 1
// WINDOWS-NEXT: ret void
+// ARM-LE-LABEL: define dso_local void @_Z28testUnnamedBitfieldMultiByteP24UnnamedBitfieldMultiByte(
+// ARM-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-LE-NEXT: [[ENTRY:.*:]]
+// ARM-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -16
+// ARM-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-LE-NEXT: ret void
+//
+// ARM-BE-LABEL: define dso_local void @_Z28testUnnamedBitfieldMultiByteP24UnnamedBitfieldMultiByte(
+// ARM-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// ARM-BE-NEXT: [[ENTRY:.*:]]
+// ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4
+// ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4
+// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 15
+// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// ARM-BE-NEXT: ret void
+//
+// AARCH64-LE-LABEL: define dso_local void @_Z28testUnnamedBitfieldMultiByteP24UnnamedBitfieldMultiByte(
+// AARCH64-LE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-LE-NEXT: [[ENTRY:.*:]]
+// AARCH64-LE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-LE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15
+// AARCH64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// AARCH64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-LE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -16
+// AARCH64-LE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-LE-NEXT: ret void
+//
+// AARCH64-BE-LABEL: define dso_local void @_Z28testUnnamedBitfieldMultiByteP24UnnamedBitfieldMultiByte(
+// AARCH64-BE-SAME: ptr noundef [[S:%.*]]) #[[ATTR0]] {
+// AARCH64-BE-NEXT: [[ENTRY:.*:]]
+// AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8
+// AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8
+// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0
+// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], -16
+// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2
+// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1
+// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 15
+// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1
+// AARCH64-BE-NEXT: ret void
//
void testUnnamedBitfieldMultiByte(struct UnnamedBitfieldMultiByte *s) {
// 2 bytes: a[0-3], unnamed[4-11], b[12-15]
More information about the llvm-branch-commits
mailing list