[llvm] abf4139 - [AggressiveInstCombine] Use DL.fitsInLegalInteger instead of TTI.isTypeLegal in consecutive load/store combine. (#220310)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 11:53:52 PDT 2026


Author: Craig Topper
Date: 2026-09-11T11:53:46-07:00
New Revision: abf41391777c822d4f5010b1f38d5a0f09102ea1

URL: https://github.com/llvm/llvm-project/commit/abf41391777c822d4f5010b1f38d5a0f09102ea1
DIFF: https://github.com/llvm/llvm-project/commit/abf41391777c822d4f5010b1f38d5a0f09102ea1.diff

LOG: [AggressiveInstCombine] Use DL.fitsInLegalInteger instead of TTI.isTypeLegal in consecutive load/store combine. (#220310)

riscv64 doesn't have a legal i32 type in the backend, but we
support i16, and i32 loads/stores. AArch64 also supports i16
loads/stores even though i16 isn't legal.

Replace TTI.isTypeLegal with DL.fitsInLegalInteger and a check for
a power of 2 number of bytes. This covers i16 and i32 for RISC-V
and i16 for AArch64.

We could further relax this to cover types that the backend can handle
by splitting, but I'd like to leave that for a future patch.

I had to update some existing tests to have more accurate datalayouts.

The RISC-V tests are reduced from existing tests from AArch64 or X86 to
show some of the load sizes that can now be matched.

Added: 
    llvm/test/Transforms/AggressiveInstCombine/RISCV/or-load.ll
    llvm/test/Transforms/AggressiveInstCombine/RISCV/store-merge.ll

Modified: 
    llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
    llvm/test/Transforms/AggressiveInstCombine/AArch64/combine_ignore_debug.ll
    llvm/test/Transforms/AggressiveInstCombine/AArch64/or-load.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 9646b2785b9f1..543af69a56d07 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1455,9 +1455,9 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
   IRBuilder<> Builder(&I);
   LoadInst *NewLoad = nullptr, *LI1 = LOps.Root;
 
-  IntegerType *WiderType = IntegerType::get(I.getContext(), LOps.LoadSize);
-  // TTI based checks if we want to proceed with wider load
-  bool Allowed = TTI.isTypeLegal(WiderType);
+  // Allow a power of 2 number of bytes that fit in a legal integer type.
+  bool Allowed = LOps.LoadSize >= 16 && isPowerOf2_64(LOps.LoadSize) &&
+                 DL.fitsInLegalInteger(LOps.LoadSize);
   if (!Allowed)
     return false;
 
@@ -1478,6 +1478,7 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
     Load1Ptr = Builder.CreatePtrAdd(Load1Ptr, Builder.getInt(Offset1));
   }
   // Generate wider load.
+  IntegerType *WiderType = IntegerType::get(I.getContext(), LOps.LoadSize);
   NewLoad = Builder.CreateAlignedLoad(WiderType, Load1Ptr, LI1->getAlign(),
                                       LI1->isVolatile(), "");
   NewLoad->takeName(LI1);
@@ -1554,9 +1555,10 @@ static bool mergeConsecutivePartStores(ArrayRef<PartStore> Parts,
   // FIXME: We could generate smaller stores if we can't produce a large one.
   const PartStore &First = Parts.front();
   LLVMContext &Ctx = First.Store->getContext();
-  Type *NewTy = Type::getIntNTy(Ctx, Width);
   unsigned Fast = 0;
-  if (!TTI.isTypeLegal(NewTy) ||
+  bool Allowed =
+      Width >= 16 && isPowerOf2_64(Width) && DL.fitsInLegalInteger(Width);
+  if (!Allowed ||
       !TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
                                           First.Store->getPointerAddressSpace(),
                                           First.Store->getAlign(), &Fast) ||
@@ -1565,6 +1567,7 @@ static bool mergeConsecutivePartStores(ArrayRef<PartStore> Parts,
 
   // Generate the combined store.
   IRBuilder<> Builder(First.Store);
+  Type *NewTy = Type::getIntNTy(Ctx, Width);
   Value *Val = First.Val;
   if (First.ValOffset != 0)
     Val = Builder.CreateLShr(Val, First.ValOffset);

diff  --git a/llvm/test/Transforms/AggressiveInstCombine/AArch64/combine_ignore_debug.ll b/llvm/test/Transforms/AggressiveInstCombine/AArch64/combine_ignore_debug.ll
index cc5714861aeb1..5fc3a8487b74c 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/AArch64/combine_ignore_debug.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/AArch64/combine_ignore_debug.ll
@@ -1,12 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
-; RUN: opt -mtriple aarch64 -aggressive-instcombine-max-scan-instrs=1 -passes="aggressive-instcombine" -S < %s | FileCheck %s -check-prefix DBG
-; RUN: opt -strip-debug -mtriple aarch64 -aggressive-instcombine-max-scan-instrs=1 -passes="aggressive-instcombine" -S < %s | FileCheck %s -check-prefix NODBG
+; RUN: opt -mtriple aarch64_be -aggressive-instcombine-max-scan-instrs=1 -passes="aggressive-instcombine" -S < %s | FileCheck %s -check-prefix DBG
+; RUN: opt -strip-debug -mtriple aarch64_be -aggressive-instcombine-max-scan-instrs=1 -passes="aggressive-instcombine" -S < %s | FileCheck %s -check-prefix NODBG
 
 ; The DBG and NODBG cases should be the same. I.e. we should optimize the DBG
 ; case too even if there is a dbg.value.
 
-target datalayout = "E"
-
 %s = type { i16, i16 }
 
 @e = global %s zeroinitializer, align 1

diff  --git a/llvm/test/Transforms/AggressiveInstCombine/AArch64/or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/AArch64/or-load.ll
index cb4c829e31e99..0a00083c340b9 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/AArch64/or-load.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/AArch64/or-load.ll
@@ -4,15 +4,19 @@
 
 define i16 @loadCombine_2consecutive(ptr %p) {
 ;
-; ALL-LABEL: @loadCombine_2consecutive(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
-; ALL-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 8
-; ALL-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
-; ALL-NEXT:    ret i16 [[O1]]
+; LE-LABEL: @loadCombine_2consecutive(
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P:%.*]], align 1
+; LE-NEXT:    ret i16 [[L1]]
+;
+; BE-LABEL: @loadCombine_2consecutive(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
+; BE-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 8
+; BE-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
+; BE-NEXT:    ret i16 [[O1]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %l1 = load i8, ptr %p
@@ -25,15 +29,19 @@ define i16 @loadCombine_2consecutive(ptr %p) {
 }
 
 define i16 @loadCombine_2consecutive_BE(ptr %p) {
-; ALL-LABEL: @loadCombine_2consecutive_BE(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
-; ALL-NEXT:    [[S1:%.*]] = shl i16 [[E1]], 8
-; ALL-NEXT:    [[O1:%.*]] = or i16 [[S1]], [[E2]]
-; ALL-NEXT:    ret i16 [[O1]]
+; LE-LABEL: @loadCombine_2consecutive_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
+; LE-NEXT:    [[S1:%.*]] = shl i16 [[E1]], 8
+; LE-NEXT:    [[O1:%.*]] = or i16 [[S1]], [[E2]]
+; LE-NEXT:    ret i16 [[O1]]
+;
+; BE-LABEL: @loadCombine_2consecutive_BE(
+; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P:%.*]], align 1
+; BE-NEXT:    ret i16 [[L1]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %l1 = load i8, ptr %p
@@ -244,26 +252,42 @@ define i32 @loadCombine_4consecutive_alias_BE(ptr %p) {
 }
 
 define i32 @loadCombine_4consecutive_alias2(ptr %p, ptr %pstr) {
-; ALL-LABEL: @loadCombine_4consecutive_alias2(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_alias2(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_alias2(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -290,26 +314,42 @@ define i32 @loadCombine_4consecutive_alias2(ptr %p, ptr %pstr) {
 }
 
 define i32 @loadCombine_4consecutive_alias2_BE(ptr %p, ptr %pstr) {
-; ALL-LABEL: @loadCombine_4consecutive_alias2_BE(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 24
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 16
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_alias2_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 24
+; LE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 16
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
+; LE-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
+; LE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_alias2_BE(
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; BE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; BE-NEXT:    [[TMP2:%.*]] = shl i32 [[TMP1]], 16
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    store i8 10, ptr [[PSTR:%.*]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
+; BE-NEXT:    [[O2:%.*]] = or i32 [[TMP2]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -336,27 +376,44 @@ define i32 @loadCombine_4consecutive_alias2_BE(ptr %p, ptr %pstr) {
 }
 
 define i32 @loadCombine_4consecutive_alias3(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_alias3(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    store i8 10, ptr [[P3]], align 1
-; ALL-NEXT:    store i8 5, ptr [[P]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_alias3(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    store i8 10, ptr [[P3]], align 1
+; LE-NEXT:    store i8 5, ptr [[P]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_alias3(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    store i8 10, ptr [[P3]], align 1
+; BE-NEXT:    store i8 5, ptr [[P]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -384,27 +441,44 @@ define i32 @loadCombine_4consecutive_alias3(ptr %p) {
 }
 
 define i32 @loadCombine_4consecutive_alias3_BE(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_alias3_BE(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    store i8 10, ptr [[P3]], align 1
-; ALL-NEXT:    store i8 5, ptr [[P]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 24
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 16
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_alias3_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    store i8 10, ptr [[P3]], align 1
+; LE-NEXT:    store i8 5, ptr [[P]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 24
+; LE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 16
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
+; LE-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
+; LE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_alias3_BE(
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; BE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; BE-NEXT:    [[TMP2:%.*]] = shl i32 [[TMP1]], 16
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    store i8 10, ptr [[P3]], align 1
+; BE-NEXT:    store i8 5, ptr [[P]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
+; BE-NEXT:    [[O2:%.*]] = or i32 [[TMP2]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -647,27 +721,44 @@ define i32 @loadCombine_4consecutive_hasOneUse3(ptr %p) {
 }
 
 define i32 @loadCombine_4consecutive_hasOneUse4(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_hasOneUse4(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    call void @use(i32 [[O1]])
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    call void @use(i32 [[O2]])
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_hasOneUse4(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; LE-NEXT:    call void @use(i32 [[TMP1]])
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    call void @use(i32 [[O2]])
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_hasOneUse4(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    call void @use(i32 [[O1]])
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    call void @use(i32 [[O2]])
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -749,20 +840,30 @@ define i32 @fold_i32_multiple_uses(ptr %input, ptr %output) {
 }
 
 define i32 @loadCombine_parLoad1(ptr %p) {
-; ALL-LABEL: @loadCombine_parLoad1(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    ret i32 [[O2]]
+; LE-LABEL: @loadCombine_parLoad1(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    ret i32 [[O2]]
+;
+; BE-LABEL: @loadCombine_parLoad1(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    ret i32 [[O2]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -2117,16 +2218,22 @@ define i32 @loadCombine_4consecutive_lower_index_comes_before(ptr %p) {
 }
 
 define i16 @loadCombine_2consecutive_badinsert(ptr %p) {
-; ALL-LABEL: @loadCombine_2consecutive_badinsert(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    store i8 0, ptr [[P1]], align 1
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
-; ALL-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 8
-; ALL-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
-; ALL-NEXT:    ret i16 [[O1]]
+; LE-LABEL: @loadCombine_2consecutive_badinsert(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    store i8 0, ptr [[P1]], align 1
+; LE-NEXT:    ret i16 [[L1]]
+;
+; BE-LABEL: @loadCombine_2consecutive_badinsert(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    store i8 0, ptr [[P1]], align 1
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
+; BE-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 8
+; BE-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
+; BE-NEXT:    ret i16 [[O1]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %l2 = load i8, ptr %p1
@@ -2192,26 +2299,42 @@ define i32 @loadCombine_4consecutive_badinsert(ptr %p) {
 }
 
 define i32 @loadCombine_4consecutive_badinsert2(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_badinsert2(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    store i8 0, ptr [[P3]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_badinsert2(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    store i8 0, ptr [[P3]], align 1
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_badinsert2(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    store i8 0, ptr [[P3]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -2365,26 +2488,42 @@ end:
 }
 
 define i32 @loadCombine_4consecutive_badinsert5(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_badinsert5(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    store i8 0, ptr [[P2]], align 1
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_badinsert5(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    store i8 0, ptr [[P2]], align 1
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_badinsert5(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    store i8 0, ptr [[P2]], align 1
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2
@@ -2411,26 +2550,43 @@ define i32 @loadCombine_4consecutive_badinsert5(ptr %p) {
 }
 
 define i32 @loadCombine_4consecutive_badinsert6(ptr %p) {
-; ALL-LABEL: @loadCombine_4consecutive_badinsert6(
-; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
-; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
-; ALL-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
-; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
-; ALL-NEXT:    store i8 0, ptr [[P3]], align 1
-; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
-; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
-; ALL-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
-; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
-; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
-; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
-; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
-; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
-; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
-; ALL-NEXT:    [[O1:%.*]] = or i32 [[S3]], [[S4]]
-; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S2]]
-; ALL-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E1]]
-; ALL-NEXT:    ret i32 [[O3]]
+; LE-LABEL: @loadCombine_4consecutive_badinsert6(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    store i8 0, ptr [[P3]], align 1
+; LE-NEXT:    [[L3:%.*]] = load i16, ptr [[P2]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L3]] to i32
+; LE-NEXT:    [[TMP2:%.*]] = shl i32 [[TMP1]], 16
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; LE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP2]], [[S2]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E1]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_badinsert6(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    store i8 0, ptr [[P3]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[S3]], [[S4]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S2]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E1]]
+; BE-NEXT:    ret i32 [[O3]]
 ;
   %p1 = getelementptr i8, ptr %p, i32 1
   %p2 = getelementptr i8, ptr %p, i32 2

diff  --git a/llvm/test/Transforms/AggressiveInstCombine/RISCV/or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/RISCV/or-load.ll
new file mode 100644
index 0000000000000..352abec985e05
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/RISCV/or-load.ll
@@ -0,0 +1,483 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple riscv64 -mattr=+unaligned-scalar-mem | FileCheck %s --check-prefixes=ALL,LE,RV64LE
+; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple riscv64be -mattr=+unaligned-scalar-mem | FileCheck %s --check-prefixes=ALL,BE,RV64BE
+; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple riscv32 -mattr=+unaligned-scalar-mem | FileCheck %s --check-prefixes=ALL,LE,RV32LE
+; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple riscv32be -mattr=+unaligned-scalar-mem | FileCheck %s --check-prefixes=ALL,BE,RV32BE
+
+define i16 @loadCombine_2consecutive(ptr %p) {
+; LE-LABEL: @loadCombine_2consecutive(
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P:%.*]], align 1
+; LE-NEXT:    ret i16 [[L1]]
+;
+; BE-LABEL: @loadCombine_2consecutive(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
+; BE-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 8
+; BE-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
+; BE-NEXT:    ret i16 [[O1]]
+;
+  %p1 = getelementptr i8, ptr %p, i32 1
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %e1 = zext i8 %l1 to i16
+  %e2 = zext i8 %l2 to i16
+  %s2 = shl i16 %e2, 8
+  %o1 = or i16 %e1, %s2
+  ret i16 %o1
+}
+
+define i16 @loadCombine_2consecutive_BE(ptr %p) {
+; LE-LABEL: @loadCombine_2consecutive_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i16
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i16
+; LE-NEXT:    [[S1:%.*]] = shl i16 [[E1]], 8
+; LE-NEXT:    [[O1:%.*]] = or i16 [[S1]], [[E2]]
+; LE-NEXT:    ret i16 [[O1]]
+;
+; BE-LABEL: @loadCombine_2consecutive_BE(
+; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P:%.*]], align 1
+; BE-NEXT:    ret i16 [[L1]]
+;
+  %p1 = getelementptr i8, ptr %p, i32 1
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %e1 = zext i8 %l1 to i16
+  %e2 = zext i8 %l2 to i16
+  %s1 = shl i16 %e1, 8
+  %o1 = or i16 %s1, %e2
+  ret i16 %o1
+}
+
+define i32 @loadCombine_4consecutive(ptr %p) {
+; LE-LABEL: @loadCombine_4consecutive(
+; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
+; LE-NEXT:    ret i32 [[L1]]
+;
+; BE-LABEL: @loadCombine_4consecutive(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
+; BE-NEXT:    ret i32 [[O3]]
+;
+  %p1 = getelementptr i8, ptr %p, i32 1
+  %p2 = getelementptr i8, ptr %p, i32 2
+  %p3 = getelementptr i8, ptr %p, i32 3
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %l3 = load i8, ptr %p2
+  %l4 = load i8, ptr %p3
+
+  %e1 = zext i8 %l1 to i32
+  %e2 = zext i8 %l2 to i32
+  %e3 = zext i8 %l3 to i32
+  %e4 = zext i8 %l4 to i32
+
+  %s2 = shl i32 %e2, 8
+  %s3 = shl i32 %e3, 16
+  %s4 = shl i32 %e4, 24
+
+  %o1 = or i32 %e1, %s2
+  %o2 = or i32 %o1, %s3
+  %o3 = or i32 %o2, %s4
+  ret i32 %o3
+}
+
+define i32 @loadCombine_4consecutive_BE(ptr %p) {
+; LE-LABEL: @loadCombine_4consecutive_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
+; LE-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 24
+; LE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 16
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 8
+; LE-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
+; LE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[E4]]
+; LE-NEXT:    ret i32 [[O3]]
+;
+; BE-LABEL: @loadCombine_4consecutive_BE(
+; BE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
+; BE-NEXT:    ret i32 [[L1]]
+;
+  %p1 = getelementptr i8, ptr %p, i32 1
+  %p2 = getelementptr i8, ptr %p, i32 2
+  %p3 = getelementptr i8, ptr %p, i32 3
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %l3 = load i8, ptr %p2
+  %l4 = load i8, ptr %p3
+
+  %e1 = zext i8 %l1 to i32
+  %e2 = zext i8 %l2 to i32
+  %e3 = zext i8 %l3 to i32
+  %e4 = zext i8 %l4 to i32
+
+  %s1 = shl i32 %e1, 24
+  %s2 = shl i32 %e2, 16
+  %s3 = shl i32 %e3, 8
+
+  %o1 = or i32 %s1, %s2
+  %o2 = or i32 %o1, %s3
+  %o3 = or i32 %o2, %e4
+  ret i32 %o3
+}
+
+define i128 @loadCombine_i128(ptr %p) {
+; RV64LE-LABEL: @loadCombine_i128(
+; RV64LE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 2
+; RV64LE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; RV64LE-NEXT:    [[L1:%.*]] = load i64, ptr [[P]], align 4
+; RV64LE-NEXT:    [[TMP1:%.*]] = zext i64 [[L1]] to i128
+; RV64LE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; RV64LE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; RV64LE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; RV64LE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; RV64LE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 64
+; RV64LE-NEXT:    [[S4:%.*]] = shl i128 [[E4]], 96
+; RV64LE-NEXT:    [[O2:%.*]] = or i128 [[TMP1]], [[S3]]
+; RV64LE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[S4]]
+; RV64LE-NEXT:    ret i128 [[O3]]
+;
+; BE-LABEL: @loadCombine_i128(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 4
+; BE-NEXT:    [[L2:%.*]] = load i32, ptr [[P1]], align 4
+; BE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; BE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; BE-NEXT:    [[E1:%.*]] = zext i32 [[L1]] to i128
+; BE-NEXT:    [[E2:%.*]] = zext i32 [[L2]] to i128
+; BE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; BE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; BE-NEXT:    [[S2:%.*]] = shl i128 [[E2]], 32
+; BE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 64
+; BE-NEXT:    [[S4:%.*]] = shl i128 [[E4]], 96
+; BE-NEXT:    [[O1:%.*]] = or i128 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i128 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[S4]]
+; BE-NEXT:    ret i128 [[O3]]
+;
+; RV32LE-LABEL: @loadCombine_i128(
+; RV32LE-NEXT:    [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; RV32LE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 2
+; RV32LE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; RV32LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 4
+; RV32LE-NEXT:    [[L2:%.*]] = load i32, ptr [[P1]], align 4
+; RV32LE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; RV32LE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; RV32LE-NEXT:    [[E1:%.*]] = zext i32 [[L1]] to i128
+; RV32LE-NEXT:    [[E2:%.*]] = zext i32 [[L2]] to i128
+; RV32LE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; RV32LE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; RV32LE-NEXT:    [[S2:%.*]] = shl i128 [[E2]], 32
+; RV32LE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 64
+; RV32LE-NEXT:    [[S4:%.*]] = shl i128 [[E4]], 96
+; RV32LE-NEXT:    [[O1:%.*]] = or i128 [[E1]], [[S2]]
+; RV32LE-NEXT:    [[O2:%.*]] = or i128 [[O1]], [[S3]]
+; RV32LE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[S4]]
+; RV32LE-NEXT:    ret i128 [[O3]]
+;
+  %p1 = getelementptr i32, ptr %p, i32 1
+  %p2 = getelementptr i32, ptr %p, i32 2
+  %p3 = getelementptr i32, ptr %p, i32 3
+  %l1 = load i32, ptr %p
+  %l2 = load i32, ptr %p1
+  %l3 = load i32, ptr %p2
+  %l4 = load i32, ptr %p3
+
+  %e1 = zext i32 %l1 to i128
+  %e2 = zext i32 %l2 to i128
+  %e3 = zext i32 %l3 to i128
+  %e4 = zext i32 %l4 to i128
+
+  %s2 = shl i128 %e2, 32
+  %s3 = shl i128 %e3, 64
+  %s4 = shl i128 %e4, 96
+
+  %o1 = or i128 %e1, %s2
+  %o2 = or i128 %o1, %s3
+  %o3 = or i128 %o2, %s4
+  ret i128 %o3
+}
+
+define i128 @loadCombine_i128_BE(ptr %p) {
+; LE-LABEL: @loadCombine_i128_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 4
+; LE-NEXT:    [[L2:%.*]] = load i32, ptr [[P1]], align 4
+; LE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; LE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; LE-NEXT:    [[E1:%.*]] = zext i32 [[L1]] to i128
+; LE-NEXT:    [[E2:%.*]] = zext i32 [[L2]] to i128
+; LE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; LE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; LE-NEXT:    [[S1:%.*]] = shl i128 [[E1]], 96
+; LE-NEXT:    [[S2:%.*]] = shl i128 [[E2]], 64
+; LE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 32
+; LE-NEXT:    [[O1:%.*]] = or i128 [[S1]], [[S2]]
+; LE-NEXT:    [[O2:%.*]] = or i128 [[O1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[E4]]
+; LE-NEXT:    ret i128 [[O3]]
+;
+; RV64BE-LABEL: @loadCombine_i128_BE(
+; RV64BE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 2
+; RV64BE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; RV64BE-NEXT:    [[L1:%.*]] = load i64, ptr [[P]], align 4
+; RV64BE-NEXT:    [[TMP1:%.*]] = zext i64 [[L1]] to i128
+; RV64BE-NEXT:    [[TMP2:%.*]] = shl i128 [[TMP1]], 64
+; RV64BE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; RV64BE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; RV64BE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; RV64BE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; RV64BE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 32
+; RV64BE-NEXT:    [[O2:%.*]] = or i128 [[TMP2]], [[S3]]
+; RV64BE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[E4]]
+; RV64BE-NEXT:    ret i128 [[O3]]
+;
+; RV32BE-LABEL: @loadCombine_i128_BE(
+; RV32BE-NEXT:    [[P1:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; RV32BE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 2
+; RV32BE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
+; RV32BE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 4
+; RV32BE-NEXT:    [[L2:%.*]] = load i32, ptr [[P1]], align 4
+; RV32BE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
+; RV32BE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
+; RV32BE-NEXT:    [[E1:%.*]] = zext i32 [[L1]] to i128
+; RV32BE-NEXT:    [[E2:%.*]] = zext i32 [[L2]] to i128
+; RV32BE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
+; RV32BE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
+; RV32BE-NEXT:    [[S1:%.*]] = shl i128 [[E1]], 96
+; RV32BE-NEXT:    [[S2:%.*]] = shl i128 [[E2]], 64
+; RV32BE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 32
+; RV32BE-NEXT:    [[O1:%.*]] = or i128 [[S1]], [[S2]]
+; RV32BE-NEXT:    [[O2:%.*]] = or i128 [[O1]], [[S3]]
+; RV32BE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[E4]]
+; RV32BE-NEXT:    ret i128 [[O3]]
+;
+  %p1 = getelementptr i32, ptr %p, i32 1
+  %p2 = getelementptr i32, ptr %p, i32 2
+  %p3 = getelementptr i32, ptr %p, i32 3
+  %l1 = load i32, ptr %p
+  %l2 = load i32, ptr %p1
+  %l3 = load i32, ptr %p2
+  %l4 = load i32, ptr %p3
+
+  %e1 = zext i32 %l1 to i128
+  %e2 = zext i32 %l2 to i128
+  %e3 = zext i32 %l3 to i128
+  %e4 = zext i32 %l4 to i128
+
+  %s1 = shl i128 %e1, 96
+  %s2 = shl i128 %e2, 64
+  %s3 = shl i128 %e3, 32
+
+  %o1 = or i128 %s1, %s2
+  %o2 = or i128 %o1, %s3
+  %o3 = or i128 %o2, %e4
+  ret i128 %o3
+}
+
+define i64 @loadCombine_i64(ptr %p) {
+; RV64LE-LABEL: @loadCombine_i64(
+; RV64LE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 2
+; RV64LE-NEXT:    ret i64 [[L1]]
+;
+; BE-LABEL: @loadCombine_i64(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i16, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i16, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i16, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
+; BE-NEXT:    [[L2:%.*]] = load i16, ptr [[P1]], align 2
+; BE-NEXT:    [[L3:%.*]] = load i16, ptr [[P2]], align 2
+; BE-NEXT:    [[L4:%.*]] = load i16, ptr [[P3]], align 2
+; BE-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i64
+; BE-NEXT:    [[E2:%.*]] = zext i16 [[L2]] to i64
+; BE-NEXT:    [[E3:%.*]] = zext i16 [[L3]] to i64
+; BE-NEXT:    [[E4:%.*]] = zext i16 [[L4]] to i64
+; BE-NEXT:    [[S2:%.*]] = shl i64 [[E2]], 16
+; BE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 32
+; BE-NEXT:    [[S4:%.*]] = shl i64 [[E4]], 48
+; BE-NEXT:    [[O1:%.*]] = or i64 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i64 [[O1]], [[S3]]
+; BE-NEXT:    [[O3:%.*]] = or i64 [[O2]], [[S4]]
+; BE-NEXT:    ret i64 [[O3]]
+;
+; RV32LE-LABEL: @loadCombine_i64(
+; RV32LE-NEXT:    [[P2:%.*]] = getelementptr i16, ptr [[P:%.*]], i32 2
+; RV32LE-NEXT:    [[P3:%.*]] = getelementptr i16, ptr [[P]], i32 3
+; RV32LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 2
+; RV32LE-NEXT:    [[TMP1:%.*]] = zext i32 [[L1]] to i64
+; RV32LE-NEXT:    [[L3:%.*]] = load i16, ptr [[P2]], align 2
+; RV32LE-NEXT:    [[L4:%.*]] = load i16, ptr [[P3]], align 2
+; RV32LE-NEXT:    [[E3:%.*]] = zext i16 [[L3]] to i64
+; RV32LE-NEXT:    [[E4:%.*]] = zext i16 [[L4]] to i64
+; RV32LE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 32
+; RV32LE-NEXT:    [[S4:%.*]] = shl i64 [[E4]], 48
+; RV32LE-NEXT:    [[O2:%.*]] = or i64 [[TMP1]], [[S3]]
+; RV32LE-NEXT:    [[O3:%.*]] = or i64 [[O2]], [[S4]]
+; RV32LE-NEXT:    ret i64 [[O3]]
+;
+  %p1 = getelementptr i16, ptr %p, i32 1
+  %p2 = getelementptr i16, ptr %p, i32 2
+  %p3 = getelementptr i16, ptr %p, i32 3
+  %l1 = load i16, ptr %p
+  %l2 = load i16, ptr %p1
+  %l3 = load i16, ptr %p2
+  %l4 = load i16, ptr %p3
+
+  %e1 = zext i16 %l1 to i64
+  %e2 = zext i16 %l2 to i64
+  %e3 = zext i16 %l3 to i64
+  %e4 = zext i16 %l4 to i64
+
+  %s2 = shl i64 %e2, 16
+  %s3 = shl i64 %e3, 32
+  %s4 = shl i64 %e4, 48
+
+  %o1 = or i64 %e1, %s2
+  %o2 = or i64 %o1, %s3
+  %o3 = or i64 %o2, %s4
+  ret i64 %o3
+}
+
+define i64 @loadCombine_i64_BE(ptr %p) {
+; LE-LABEL: @loadCombine_i64_BE(
+; LE-NEXT:    [[P1:%.*]] = getelementptr i16, ptr [[P:%.*]], i32 1
+; LE-NEXT:    [[P2:%.*]] = getelementptr i16, ptr [[P]], i32 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i16, ptr [[P]], i32 3
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
+; LE-NEXT:    [[L2:%.*]] = load i16, ptr [[P1]], align 2
+; LE-NEXT:    [[L3:%.*]] = load i16, ptr [[P2]], align 2
+; LE-NEXT:    [[L4:%.*]] = load i16, ptr [[P3]], align 2
+; LE-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i64
+; LE-NEXT:    [[E2:%.*]] = zext i16 [[L2]] to i64
+; LE-NEXT:    [[E3:%.*]] = zext i16 [[L3]] to i64
+; LE-NEXT:    [[E4:%.*]] = zext i16 [[L4]] to i64
+; LE-NEXT:    [[S1:%.*]] = shl i64 [[E1]], 48
+; LE-NEXT:    [[S2:%.*]] = shl i64 [[E2]], 32
+; LE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 16
+; LE-NEXT:    [[O1:%.*]] = or i64 [[S1]], [[S2]]
+; LE-NEXT:    [[O2:%.*]] = or i64 [[O1]], [[S3]]
+; LE-NEXT:    [[O3:%.*]] = or i64 [[O2]], [[E4]]
+; LE-NEXT:    ret i64 [[O3]]
+;
+; RV64BE-LABEL: @loadCombine_i64_BE(
+; RV64BE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 2
+; RV64BE-NEXT:    ret i64 [[L1]]
+;
+; RV32BE-LABEL: @loadCombine_i64_BE(
+; RV32BE-NEXT:    [[P2:%.*]] = getelementptr i16, ptr [[P:%.*]], i32 2
+; RV32BE-NEXT:    [[P3:%.*]] = getelementptr i16, ptr [[P]], i32 3
+; RV32BE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 2
+; RV32BE-NEXT:    [[TMP1:%.*]] = zext i32 [[L1]] to i64
+; RV32BE-NEXT:    [[TMP2:%.*]] = shl i64 [[TMP1]], 32
+; RV32BE-NEXT:    [[L3:%.*]] = load i16, ptr [[P2]], align 2
+; RV32BE-NEXT:    [[L4:%.*]] = load i16, ptr [[P3]], align 2
+; RV32BE-NEXT:    [[E3:%.*]] = zext i16 [[L3]] to i64
+; RV32BE-NEXT:    [[E4:%.*]] = zext i16 [[L4]] to i64
+; RV32BE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 16
+; RV32BE-NEXT:    [[O2:%.*]] = or i64 [[TMP2]], [[S3]]
+; RV32BE-NEXT:    [[O3:%.*]] = or i64 [[O2]], [[E4]]
+; RV32BE-NEXT:    ret i64 [[O3]]
+;
+  %p1 = getelementptr i16, ptr %p, i32 1
+  %p2 = getelementptr i16, ptr %p, i32 2
+  %p3 = getelementptr i16, ptr %p, i32 3
+  %l1 = load i16, ptr %p
+  %l2 = load i16, ptr %p1
+  %l3 = load i16, ptr %p2
+  %l4 = load i16, ptr %p3
+
+  %e1 = zext i16 %l1 to i64
+  %e2 = zext i16 %l2 to i64
+  %e3 = zext i16 %l3 to i64
+  %e4 = zext i16 %l4 to i64
+
+  %s1 = shl i64 %e1, 48
+  %s2 = shl i64 %e2, 32
+  %s3 = shl i64 %e3, 16
+
+  %o1 = or i64 %s1, %s2
+  %o2 = or i64 %o1, %s3
+  %o3 = or i64 %o2, %e4
+  ret i64 %o3
+}
+
+define i32 @loadCombine_3consecutive(ptr %p) {
+; LE-LABEL: @loadCombine_3consecutive(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
+; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L1]] to i32
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; LE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S3]]
+; LE-NEXT:    ret i32 [[O2]]
+;
+; BE-LABEL: @loadCombine_3consecutive(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
+; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
+; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
+; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
+; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
+; BE-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
+; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
+; BE-NEXT:    ret i32 [[O2]]
+;
+  %p1 = getelementptr i8, ptr %p, i32 1
+  %p2 = getelementptr i8, ptr %p, i32 2
+  %p3 = getelementptr i8, ptr %p, i32 3
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %l3 = load i8, ptr %p2
+
+  %e1 = zext i8 %l1 to i32
+  %e2 = zext i8 %l2 to i32
+  %e3 = zext i8 %l3 to i32
+
+  %s2 = shl i32 %e2, 8
+  %s3 = shl i32 %e3, 16
+
+  %o1 = or i32 %e1, %s2
+  %o2 = or i32 %o1, %s3
+  ret i32 %o2
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ALL: {{.*}}

diff  --git a/llvm/test/Transforms/AggressiveInstCombine/RISCV/store-merge.ll b/llvm/test/Transforms/AggressiveInstCombine/RISCV/store-merge.ll
new file mode 100644
index 0000000000000..e87ff60c1c06d
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/RISCV/store-merge.ll
@@ -0,0 +1,308 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=aggressive-instcombine -mtriple=riscv64-unknown-linux-gnu -mattr=+unaligned-scalar-mem < %s | FileCheck %s --check-prefixes=CHECK,RV64
+; RUN: opt -S -passes=aggressive-instcombine -mtriple=riscv32-unknown-linux-gnu -mattr=+unaligned-scalar-mem < %s | FileCheck %s --check-prefixes=CHECK,RV32
+
+define void @test_i16(i16 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i16(
+; CHECK-SAME: i16 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    store i16 [[X]], ptr [[P]], align 1
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i16 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i16 %x, 8
+  %x.1 = trunc i16 %shr.1 to i8
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i8 %x.1, ptr %gep.1
+  ret void
+}
+
+define void @test_i32_i8_parts(i32 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i32_i8_parts(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    store i32 [[X]], ptr [[P]], align 1
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i32 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i32 %x, 8
+  %x.1 = trunc i32 %shr.1 to i8
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i8 %x.1, ptr %gep.1
+  %shr.2 = lshr i32 %x, 16
+  %x.2 = trunc i32 %shr.2 to i8
+  %gep.2 = getelementptr i8, ptr %p, i64 2
+  store i8 %x.2, ptr %gep.2
+  %shr.3 = lshr i32 %x, 24
+  %x.3 = trunc i32 %shr.3 to i8
+  %gep.3 = getelementptr i8, ptr %p, i64 3
+  store i8 %x.3, ptr %gep.3
+  ret void
+}
+
+define void @test_i32_i16_parts(i32 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i32_i16_parts(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    store i32 [[X]], ptr [[P]], align 2
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i32 %x to i16
+  store i16 %x.0, ptr %p
+  %shr.1 = lshr i32 %x, 16
+  %x.1 = trunc i32 %shr.1 to i16
+  %gep.1 = getelementptr i8, ptr %p, i64 2
+  store i16 %x.1, ptr %gep.1
+  ret void
+}
+
+define void @test_i32_mixed_parts(i32 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i32_mixed_parts(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    store i32 [[X]], ptr [[P]], align 1
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i32 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i32 %x, 8
+  %x.1 = trunc i32 %shr.1 to i16
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i16 %x.1, ptr %gep.1
+  %shr.3 = lshr i32 %x, 24
+  %x.3 = trunc i32 %shr.3 to i8
+  %gep.3 = getelementptr i8, ptr %p, i64 3
+  store i8 %x.3, ptr %gep.3
+  ret void
+}
+
+define void @test_i64(i64 %x, ptr %p) {
+; RV64-LABEL: define void @test_i64(
+; RV64-SAME: i64 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; RV64-NEXT:    store i64 [[X]], ptr [[P]], align 1
+; RV64-NEXT:    ret void
+;
+; RV32-LABEL: define void @test_i64(
+; RV32-SAME: i64 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; RV32-NEXT:    [[X_0:%.*]] = trunc i64 [[X]] to i8
+; RV32-NEXT:    store i8 [[X_0]], ptr [[P]], align 1
+; RV32-NEXT:    [[SHR_1:%.*]] = lshr i64 [[X]], 8
+; RV32-NEXT:    [[X_1:%.*]] = trunc i64 [[SHR_1]] to i8
+; RV32-NEXT:    [[GEP_1:%.*]] = getelementptr i8, ptr [[P]], i64 1
+; RV32-NEXT:    store i8 [[X_1]], ptr [[GEP_1]], align 1
+; RV32-NEXT:    [[SHR_2:%.*]] = lshr i64 [[X]], 16
+; RV32-NEXT:    [[X_2:%.*]] = trunc i64 [[SHR_2]] to i8
+; RV32-NEXT:    [[GEP_2:%.*]] = getelementptr i8, ptr [[P]], i64 2
+; RV32-NEXT:    store i8 [[X_2]], ptr [[GEP_2]], align 1
+; RV32-NEXT:    [[SHR_3:%.*]] = lshr i64 [[X]], 24
+; RV32-NEXT:    [[X_3:%.*]] = trunc i64 [[SHR_3]] to i8
+; RV32-NEXT:    [[GEP_3:%.*]] = getelementptr i8, ptr [[P]], i64 3
+; RV32-NEXT:    store i8 [[X_3]], ptr [[GEP_3]], align 1
+; RV32-NEXT:    [[SHR_4:%.*]] = lshr i64 [[X]], 32
+; RV32-NEXT:    [[X_4:%.*]] = trunc i64 [[SHR_4]] to i8
+; RV32-NEXT:    [[GEP_4:%.*]] = getelementptr i8, ptr [[P]], i64 4
+; RV32-NEXT:    store i8 [[X_4]], ptr [[GEP_4]], align 1
+; RV32-NEXT:    [[SHR_5:%.*]] = lshr i64 [[X]], 40
+; RV32-NEXT:    [[X_5:%.*]] = trunc i64 [[SHR_5]] to i8
+; RV32-NEXT:    [[GEP_5:%.*]] = getelementptr i8, ptr [[P]], i64 5
+; RV32-NEXT:    store i8 [[X_5]], ptr [[GEP_5]], align 1
+; RV32-NEXT:    [[SHR_6:%.*]] = lshr i64 [[X]], 48
+; RV32-NEXT:    [[X_6:%.*]] = trunc i64 [[SHR_6]] to i8
+; RV32-NEXT:    [[GEP_6:%.*]] = getelementptr i8, ptr [[P]], i64 6
+; RV32-NEXT:    store i8 [[X_6]], ptr [[GEP_6]], align 1
+; RV32-NEXT:    [[SHR_7:%.*]] = lshr i64 [[X]], 56
+; RV32-NEXT:    [[X_7:%.*]] = trunc i64 [[SHR_7]] to i8
+; RV32-NEXT:    [[GEP_7:%.*]] = getelementptr i8, ptr [[P]], i64 7
+; RV32-NEXT:    store i8 [[X_7]], ptr [[GEP_7]], align 1
+; RV32-NEXT:    ret void
+;
+  %x.0 = trunc i64 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i64 %x, 8
+  %x.1 = trunc i64 %shr.1 to i8
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i8 %x.1, ptr %gep.1
+  %shr.2 = lshr i64 %x, 16
+  %x.2 = trunc i64 %shr.2 to i8
+  %gep.2 = getelementptr i8, ptr %p, i64 2
+  store i8 %x.2, ptr %gep.2
+  %shr.3 = lshr i64 %x, 24
+  %x.3 = trunc i64 %shr.3 to i8
+  %gep.3 = getelementptr i8, ptr %p, i64 3
+  store i8 %x.3, ptr %gep.3
+  %shr.4 = lshr i64 %x, 32
+  %x.4 = trunc i64 %shr.4 to i8
+  %gep.4 = getelementptr i8, ptr %p, i64 4
+  store i8 %x.4, ptr %gep.4
+  %shr.5 = lshr i64 %x, 40
+  %x.5 = trunc i64 %shr.5 to i8
+  %gep.5 = getelementptr i8, ptr %p, i64 5
+  store i8 %x.5, ptr %gep.5
+  %shr.6 = lshr i64 %x, 48
+  %x.6 = trunc i64 %shr.6 to i8
+  %gep.6 = getelementptr i8, ptr %p, i64 6
+  store i8 %x.6, ptr %gep.6
+  %shr.7 = lshr i64 %x, 56
+  %x.7 = trunc i64 %shr.7 to i8
+  %gep.7 = getelementptr i8, ptr %p, i64 7
+  store i8 %x.7, ptr %gep.7
+  ret void
+}
+
+define void @test_i128(i128 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i128(
+; CHECK-SAME: i128 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[X_0:%.*]] = trunc i128 [[X]] to i8
+; CHECK-NEXT:    store i8 [[X_0]], ptr [[P]], align 1
+; CHECK-NEXT:    [[SHR_1:%.*]] = lshr i128 [[X]], 8
+; CHECK-NEXT:    [[X_1:%.*]] = trunc i128 [[SHR_1]] to i8
+; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i8, ptr [[P]], i64 1
+; CHECK-NEXT:    store i8 [[X_1]], ptr [[GEP_1]], align 1
+; CHECK-NEXT:    [[SHR_2:%.*]] = lshr i128 [[X]], 16
+; CHECK-NEXT:    [[X_2:%.*]] = trunc i128 [[SHR_2]] to i8
+; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr i8, ptr [[P]], i64 2
+; CHECK-NEXT:    store i8 [[X_2]], ptr [[GEP_2]], align 1
+; CHECK-NEXT:    [[SHR_3:%.*]] = lshr i128 [[X]], 24
+; CHECK-NEXT:    [[X_3:%.*]] = trunc i128 [[SHR_3]] to i8
+; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr i8, ptr [[P]], i64 3
+; CHECK-NEXT:    store i8 [[X_3]], ptr [[GEP_3]], align 1
+; CHECK-NEXT:    [[SHR_4:%.*]] = lshr i128 [[X]], 32
+; CHECK-NEXT:    [[X_4:%.*]] = trunc i128 [[SHR_4]] to i8
+; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr i8, ptr [[P]], i64 4
+; CHECK-NEXT:    store i8 [[X_4]], ptr [[GEP_4]], align 1
+; CHECK-NEXT:    [[SHR_5:%.*]] = lshr i128 [[X]], 40
+; CHECK-NEXT:    [[X_5:%.*]] = trunc i128 [[SHR_5]] to i8
+; CHECK-NEXT:    [[GEP_5:%.*]] = getelementptr i8, ptr [[P]], i64 5
+; CHECK-NEXT:    store i8 [[X_5]], ptr [[GEP_5]], align 1
+; CHECK-NEXT:    [[SHR_6:%.*]] = lshr i128 [[X]], 48
+; CHECK-NEXT:    [[X_6:%.*]] = trunc i128 [[SHR_6]] to i8
+; CHECK-NEXT:    [[GEP_6:%.*]] = getelementptr i8, ptr [[P]], i64 6
+; CHECK-NEXT:    store i8 [[X_6]], ptr [[GEP_6]], align 1
+; CHECK-NEXT:    [[SHR_7:%.*]] = lshr i128 [[X]], 56
+; CHECK-NEXT:    [[X_7:%.*]] = trunc i128 [[SHR_7]] to i8
+; CHECK-NEXT:    [[GEP_7:%.*]] = getelementptr i8, ptr [[P]], i64 7
+; CHECK-NEXT:    store i8 [[X_7]], ptr [[GEP_7]], align 1
+; CHECK-NEXT:    [[SHR_8:%.*]] = lshr i128 [[X]], 64
+; CHECK-NEXT:    [[X_8:%.*]] = trunc i128 [[SHR_8]] to i8
+; CHECK-NEXT:    [[GEP_8:%.*]] = getelementptr i8, ptr [[P]], i64 8
+; CHECK-NEXT:    store i8 [[X_8]], ptr [[GEP_8]], align 1
+; CHECK-NEXT:    [[SHR_9:%.*]] = lshr i128 [[X]], 72
+; CHECK-NEXT:    [[X_9:%.*]] = trunc i128 [[SHR_9]] to i8
+; CHECK-NEXT:    [[GEP_9:%.*]] = getelementptr i8, ptr [[P]], i64 9
+; CHECK-NEXT:    store i8 [[X_9]], ptr [[GEP_9]], align 1
+; CHECK-NEXT:    [[SHR_10:%.*]] = lshr i128 [[X]], 80
+; CHECK-NEXT:    [[X_10:%.*]] = trunc i128 [[SHR_10]] to i8
+; CHECK-NEXT:    [[GEP_10:%.*]] = getelementptr i8, ptr [[P]], i64 10
+; CHECK-NEXT:    store i8 [[X_10]], ptr [[GEP_10]], align 1
+; CHECK-NEXT:    [[SHR_11:%.*]] = lshr i128 [[X]], 88
+; CHECK-NEXT:    [[X_11:%.*]] = trunc i128 [[SHR_11]] to i8
+; CHECK-NEXT:    [[GEP_11:%.*]] = getelementptr i8, ptr [[P]], i64 11
+; CHECK-NEXT:    store i8 [[X_11]], ptr [[GEP_11]], align 1
+; CHECK-NEXT:    [[SHR_12:%.*]] = lshr i128 [[X]], 96
+; CHECK-NEXT:    [[X_12:%.*]] = trunc i128 [[SHR_12]] to i8
+; CHECK-NEXT:    [[GEP_12:%.*]] = getelementptr i8, ptr [[P]], i64 12
+; CHECK-NEXT:    store i8 [[X_12]], ptr [[GEP_12]], align 1
+; CHECK-NEXT:    [[SHR_13:%.*]] = lshr i128 [[X]], 104
+; CHECK-NEXT:    [[X_13:%.*]] = trunc i128 [[SHR_13]] to i8
+; CHECK-NEXT:    [[GEP_13:%.*]] = getelementptr i8, ptr [[P]], i64 13
+; CHECK-NEXT:    store i8 [[X_13]], ptr [[GEP_13]], align 1
+; CHECK-NEXT:    [[SHR_14:%.*]] = lshr i128 [[X]], 112
+; CHECK-NEXT:    [[X_14:%.*]] = trunc i128 [[SHR_14]] to i8
+; CHECK-NEXT:    [[GEP_14:%.*]] = getelementptr i8, ptr [[P]], i64 14
+; CHECK-NEXT:    store i8 [[X_14]], ptr [[GEP_14]], align 1
+; CHECK-NEXT:    [[SHR_15:%.*]] = lshr i128 [[X]], 120
+; CHECK-NEXT:    [[X_15:%.*]] = trunc i128 [[SHR_15]] to i8
+; CHECK-NEXT:    [[GEP_15:%.*]] = getelementptr i8, ptr [[P]], i64 15
+; CHECK-NEXT:    store i8 [[X_15]], ptr [[GEP_15]], align 1
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i128 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i128 %x, 8
+  %x.1 = trunc i128 %shr.1 to i8
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i8 %x.1, ptr %gep.1
+  %shr.2 = lshr i128 %x, 16
+  %x.2 = trunc i128 %shr.2 to i8
+  %gep.2 = getelementptr i8, ptr %p, i64 2
+  store i8 %x.2, ptr %gep.2
+  %shr.3 = lshr i128 %x, 24
+  %x.3 = trunc i128 %shr.3 to i8
+  %gep.3 = getelementptr i8, ptr %p, i64 3
+  store i8 %x.3, ptr %gep.3
+  %shr.4 = lshr i128 %x, 32
+  %x.4 = trunc i128 %shr.4 to i8
+  %gep.4 = getelementptr i8, ptr %p, i64 4
+  store i8 %x.4, ptr %gep.4
+  %shr.5 = lshr i128 %x, 40
+  %x.5 = trunc i128 %shr.5 to i8
+  %gep.5 = getelementptr i8, ptr %p, i64 5
+  store i8 %x.5, ptr %gep.5
+  %shr.6 = lshr i128 %x, 48
+  %x.6 = trunc i128 %shr.6 to i8
+  %gep.6 = getelementptr i8, ptr %p, i64 6
+  store i8 %x.6, ptr %gep.6
+  %shr.7 = lshr i128 %x, 56
+  %x.7 = trunc i128 %shr.7 to i8
+  %gep.7 = getelementptr i8, ptr %p, i64 7
+  store i8 %x.7, ptr %gep.7
+  %shr.8 = lshr i128 %x, 64
+  %x.8 = trunc i128 %shr.8 to i8
+  %gep.8 = getelementptr i8, ptr %p, i64 8
+  store i8 %x.8, ptr %gep.8
+  %shr.9 = lshr i128 %x, 72
+  %x.9 = trunc i128 %shr.9 to i8
+  %gep.9 = getelementptr i8, ptr %p, i64 9
+  store i8 %x.9, ptr %gep.9
+  %shr.10 = lshr i128 %x, 80
+  %x.10 = trunc i128 %shr.10 to i8
+  %gep.10 = getelementptr i8, ptr %p, i64 10
+  store i8 %x.10, ptr %gep.10
+  %shr.11 = lshr i128 %x, 88
+  %x.11 = trunc i128 %shr.11 to i8
+  %gep.11 = getelementptr i8, ptr %p, i64 11
+  store i8 %x.11, ptr %gep.11
+  %shr.12 = lshr i128 %x, 96
+  %x.12 = trunc i128 %shr.12 to i8
+  %gep.12 = getelementptr i8, ptr %p, i64 12
+  store i8 %x.12, ptr %gep.12
+  %shr.13 = lshr i128 %x, 104
+  %x.13 = trunc i128 %shr.13 to i8
+  %gep.13 = getelementptr i8, ptr %p, i64 13
+  store i8 %x.13, ptr %gep.13
+  %shr.14 = lshr i128 %x, 112
+  %x.14 = trunc i128 %shr.14 to i8
+  %gep.14 = getelementptr i8, ptr %p, i64 14
+  store i8 %x.14, ptr %gep.14
+  %shr.15 = lshr i128 %x, 120
+  %x.15 = trunc i128 %shr.15 to i8
+  %gep.15 = getelementptr i8, ptr %p, i64 15
+  store i8 %x.15, ptr %gep.15
+  ret void
+}
+
+define void @test_i24_i8_parts(i32 %x, ptr %p) {
+; CHECK-LABEL: define void @test_i24_i8_parts(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[X_0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT:    store i8 [[X_0]], ptr [[P]], align 1
+; CHECK-NEXT:    [[SHR_1:%.*]] = lshr i32 [[X]], 8
+; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[SHR_1]] to i8
+; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i8, ptr [[P]], i64 1
+; CHECK-NEXT:    store i8 [[X_1]], ptr [[GEP_1]], align 1
+; CHECK-NEXT:    [[SHR_2:%.*]] = lshr i32 [[X]], 16
+; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[SHR_2]] to i8
+; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr i8, ptr [[P]], i64 2
+; CHECK-NEXT:    store i8 [[X_2]], ptr [[GEP_2]], align 1
+; CHECK-NEXT:    ret void
+;
+  %x.0 = trunc i32 %x to i8
+  store i8 %x.0, ptr %p
+  %shr.1 = lshr i32 %x, 8
+  %x.1 = trunc i32 %shr.1 to i8
+  %gep.1 = getelementptr i8, ptr %p, i64 1
+  store i8 %x.1, ptr %gep.1
+  %shr.2 = lshr i32 %x, 16
+  %x.2 = trunc i32 %shr.2 to i8
+  %gep.2 = getelementptr i8, ptr %p, i64 2
+  store i8 %x.2, ptr %gep.2
+  ret void
+}


        


More information about the llvm-commits mailing list