[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