llvm/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-none-eabi -mattr=avx2 -data-layout="e-n64" -S | FileCheck %s --check-prefixes=ALL,LE
; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-none-eabi -mattr=avx2 -data-layout="E-n64" -S | FileCheck %s --check-prefixes=ALL,BE

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 i32 @loadCombine_4consecutive_alias(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_alias(
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
; LE-NEXT:    store i8 10, ptr [[P]], align 1
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_alias(
; 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:    store i8 10, 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
  store i8 10, 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_alias_BE(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_alias_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:    store i8 10, 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_alias_BE(
; BE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
; BE-NEXT:    store i8 10, 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
  store i8 10, 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 i32 @loadCombine_4consecutive_alias2(ptr %p, ptr %pstr) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  store i8 10, ptr %pstr
  %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_alias2_BE(ptr %p, ptr %pstr) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  store i8 10, ptr %pstr
  %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 i32 @loadCombine_4consecutive_alias3(ptr %p) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  store i8 10, ptr %p3
  store i8 5, ptr %p
  %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_alias3_BE(ptr %p) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  store i8 10, ptr %p3
  store i8 5, ptr %p
  %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 i32 @loadCombine_4consecutive_with_alias4(ptr %p, ptr %ps) {
; ALL-LABEL: @loadCombine_4consecutive_with_alias4(
; 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:    [[PS1:%.*]] = getelementptr i8, ptr [[PS:%.*]], i32 1
; ALL-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i32 2
; ALL-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i32 3
; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
; ALL-NEXT:    store i8 10, ptr [[PS]], align 1
; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
; ALL-NEXT:    store i8 10, ptr [[PS1]], align 1
; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT:    store i8 10, ptr [[PS2]], align 1
; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
; ALL-NEXT:    store i8 10, ptr [[PS3]], 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]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %p2 = getelementptr i8, ptr %p, i32 2
  %p3 = getelementptr i8, ptr %p, i32 3
  %ps1 = getelementptr i8, ptr %ps, i32 1
  %ps2 = getelementptr i8, ptr %ps, i32 2
  %ps3 = getelementptr i8, ptr %ps, i32 3
  %l1 = load i8, ptr %p
  store i8 10, ptr %ps
  %l2 = load i8, ptr %p1
  store i8 10, ptr %ps1
  %l3 = load i8, ptr %p2
  store i8 10, ptr %ps2
  %l4 = load i8, ptr %p3
  store i8 10, ptr %ps3

  %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
}

declare void @use(i8)
declare void @use2(i32)

define i32 @loadCombine_4consecutive_hasOneUse1(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_hasOneUse1(
; 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:    call void @use(i8 [[L1]])
; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
; ALL-NEXT:    call void @use(i8 [[L2]])
; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT:    call void @use(i8 [[L3]])
; ALL-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
; ALL-NEXT:    call void @use(i8 [[L4]])
; 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]]
;
  %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
  call void @use(i8 %l1)
  %l2 = load i8, ptr %p1
  call void @use(i8 %l2)
  %l3 = load i8, ptr %p2
  call void @use(i8 %l3)
  %l4 = load i8, ptr %p3
  call void @use(i8 %l4)

  %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_hasOneUse2(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_hasOneUse2(
; 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:    call void @use(i32 [[E1]])
; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; ALL-NEXT:    call void @use(i32 [[E2]])
; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
; ALL-NEXT:    call void @use(i32 [[E3]])
; ALL-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
; ALL-NEXT:    call void @use(i32 [[E4]])
; 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]]
;
  %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
  call void @use(i32 %e1)
  %e2 = zext i8 %l2 to i32
  call void @use(i32 %e2)
  %e3 = zext i8 %l3 to i32
  call void @use(i32 %e3)
  %e4 = zext i8 %l4 to i32
  call void @use(i32 %e4)

  %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_hasOneUse3(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_hasOneUse3(
; 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:    call void @use(i32 [[S2]])
; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
; ALL-NEXT:    call void @use(i32 [[S3]])
; ALL-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
; ALL-NEXT:    call void @use(i32 [[S4]])
; 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]]
;
  %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
  call void @use(i32 %s2)
  %s3 = shl i32 %e3, 16
  call void @use(i32 %s3)
  %s4 = shl i32 %e4, 24
  call void @use(i32 %s4)

  %o1 = or i32 %e1, %s2
  %o2 = or i32 %o1, %s3
  %o3 = or i32 %o2, %s4
  ret i32 %o3
}

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]]
;
  %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
  call void @use(i32 %o1)
  %o2 = or i32 %o1, %s3
  call void @use(i32 %o2)
  %o3 = or i32 %o2, %s4
  ret i32 %o3
}

define i32 @loadCombine_parLoad1(ptr %p) {
; 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
  %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
}

define i128 @loadCombine_i128(ptr %p) {
; LE-LABEL: @loadCombine_i128(
; LE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 2
; LE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
; LE-NEXT:    [[L1:%.*]] = load i64, ptr [[P]], align 4
; LE-NEXT:    [[TMP1:%.*]] = zext i64 [[L1]] to i128
; LE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
; LE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
; LE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
; LE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
; LE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 64
; LE-NEXT:    [[S4:%.*]] = shl i128 [[E4]], 96
; LE-NEXT:    [[O2:%.*]] = or i128 [[TMP1]], [[S3]]
; LE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[S4]]
; LE-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]]
;
  %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]]
;
; BE-LABEL: @loadCombine_i128_BE(
; BE-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 2
; BE-NEXT:    [[P3:%.*]] = getelementptr i32, ptr [[P]], i32 3
; BE-NEXT:    [[L1:%.*]] = load i64, ptr [[P]], align 4
; BE-NEXT:    [[TMP1:%.*]] = zext i64 [[L1]] to i128
; BE-NEXT:    [[TMP2:%.*]] = shl i128 [[TMP1]], 64
; BE-NEXT:    [[L3:%.*]] = load i32, ptr [[P2]], align 4
; BE-NEXT:    [[L4:%.*]] = load i32, ptr [[P3]], align 4
; BE-NEXT:    [[E3:%.*]] = zext i32 [[L3]] to i128
; BE-NEXT:    [[E4:%.*]] = zext i32 [[L4]] to i128
; BE-NEXT:    [[S3:%.*]] = shl i128 [[E3]], 32
; BE-NEXT:    [[O2:%.*]] = or i128 [[TMP2]], [[S3]]
; BE-NEXT:    [[O3:%.*]] = or i128 [[O2]], [[E4]]
; BE-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) {
; LE-LABEL: @loadCombine_i64(
; LE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 2
; LE-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]]
;
  %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]]
;
; BE-LABEL: @loadCombine_i64_BE(
; BE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 2
; BE-NEXT:    ret i64 [[L1]]
;
  %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 i16 @loadCombine_2consecutive_atomic(ptr %p) {
; ALL-LABEL: @loadCombine_2consecutive_atomic(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; ALL-NEXT:    [[L1:%.*]] = load atomic i8, ptr [[P]] monotonic, align 1
; ALL-NEXT:    [[L2:%.*]] = load atomic i8, ptr [[P1]] monotonic, 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]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %l1 = load atomic i8, ptr %p monotonic, align 1
  %l2 = load atomic i8, ptr %p1 monotonic, align 1
  %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_volatile(ptr %p) {
; ALL-LABEL: @loadCombine_2consecutive_volatile(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; ALL-NEXT:    [[L1:%.*]] = load volatile i8, ptr [[P]], align 1
; ALL-NEXT:    [[L2:%.*]] = load volatile 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]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %l1 = load volatile i8, ptr %p, align 1
  %l2 = load volatile i8, ptr %p1, align 1
  %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_separateBB(ptr %p) {
; ALL-LABEL: @loadCombine_2consecutive_separateBB(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; ALL-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
; ALL-NEXT:    br label [[BB2:%.*]]
; ALL:       bb2:
; 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]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %l1 = load i8, ptr %p, align 1
  br label %bb2

bb2:
  %l2 = load i8, ptr %p1, align 1
  %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_separateptr(ptr %p, ptr %p2) {
; ALL-LABEL: @loadCombine_2consecutive_separateptr(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P2:%.*]], 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]]
;
  %p1 = getelementptr i8, ptr %p2, i32 1
  %l1 = load i8, ptr %p, align 1
  %l2 = load i8, ptr %p1, align 1
  %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 i64 @load64_farLoads(ptr %ptr) {
; LE-LABEL: @load64_farLoads(
; LE-NEXT:  entry:
; LE-NEXT:    [[TMP0:%.*]] = load i64, ptr [[PTR:%.*]], align 1
; LE-NEXT:    ret i64 [[TMP0]]
;
; BE-LABEL: @load64_farLoads(
; BE-NEXT:  entry:
; BE-NEXT:    [[TMP0:%.*]] = load i8, ptr [[PTR:%.*]], align 1
; BE-NEXT:    [[CONV:%.*]] = zext i8 [[TMP0]] to i64
; BE-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
; BE-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
; BE-NEXT:    [[CONV2:%.*]] = zext i8 [[TMP1]] to i64
; BE-NEXT:    [[SHL:%.*]] = shl i64 [[CONV2]], 8
; BE-NEXT:    [[OR:%.*]] = or i64 [[CONV]], [[SHL]]
; BE-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
; BE-NEXT:    [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX3]], align 1
; BE-NEXT:    [[CONV4:%.*]] = zext i8 [[TMP2]] to i64
; BE-NEXT:    [[SHL5:%.*]] = shl i64 [[CONV4]], 16
; BE-NEXT:    [[OR6:%.*]] = or i64 [[OR]], [[SHL5]]
; BE-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
; BE-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX7]], align 1
; BE-NEXT:    [[CONV8:%.*]] = zext i8 [[TMP3]] to i64
; BE-NEXT:    [[SHL9:%.*]] = shl i64 [[CONV8]], 24
; BE-NEXT:    [[OR10:%.*]] = or i64 [[OR6]], [[SHL9]]
; BE-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 4
; BE-NEXT:    [[TMP4:%.*]] = load i8, ptr [[ARRAYIDX11]], align 1
; BE-NEXT:    [[CONV12:%.*]] = zext i8 [[TMP4]] to i64
; BE-NEXT:    [[SHL13:%.*]] = shl i64 [[CONV12]], 32
; BE-NEXT:    [[OR14:%.*]] = or i64 [[OR10]], [[SHL13]]
; BE-NEXT:    [[ARRAYIDX15:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 5
; BE-NEXT:    [[TMP5:%.*]] = load i8, ptr [[ARRAYIDX15]], align 1
; BE-NEXT:    [[CONV16:%.*]] = zext i8 [[TMP5]] to i64
; BE-NEXT:    [[SHL17:%.*]] = shl i64 [[CONV16]], 40
; BE-NEXT:    [[OR18:%.*]] = or i64 [[OR14]], [[SHL17]]
; BE-NEXT:    [[ARRAYIDX19:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 6
; BE-NEXT:    [[TMP6:%.*]] = load i8, ptr [[ARRAYIDX19]], align 1
; BE-NEXT:    [[CONV20:%.*]] = zext i8 [[TMP6]] to i64
; BE-NEXT:    [[SHL21:%.*]] = shl i64 [[CONV20]], 48
; BE-NEXT:    [[OR22:%.*]] = or i64 [[OR18]], [[SHL21]]
; BE-NEXT:    [[ARRAYIDX23:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 7
; BE-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ARRAYIDX23]], align 1
; BE-NEXT:    [[CONV24:%.*]] = zext i8 [[TMP7]] to i64
; BE-NEXT:    [[SHL25:%.*]] = shl i64 [[CONV24]], 56
; BE-NEXT:    [[OR26:%.*]] = or i64 [[OR22]], [[SHL25]]
; BE-NEXT:    ret i64 [[OR26]]
;
entry:
  %0 = load i8, ptr %ptr, align 1
  %conv = zext i8 %0 to i64
  %arrayidx1 = getelementptr inbounds i8, ptr %ptr, i64 1
  %1 = load i8, ptr %arrayidx1, align 1
  %conv2 = zext i8 %1 to i64
  %shl = shl i64 %conv2, 8
  %or = or i64 %conv, %shl
  %arrayidx3 = getelementptr inbounds i8, ptr %ptr, i64 2
  %2 = load i8, ptr %arrayidx3, align 1
  %conv4 = zext i8 %2 to i64
  %shl5 = shl i64 %conv4, 16
  %or6 = or i64 %or, %shl5
  %arrayidx7 = getelementptr inbounds i8, ptr %ptr, i64 3
  %3 = load i8, ptr %arrayidx7, align 1
  %conv8 = zext i8 %3 to i64
  %shl9 = shl i64 %conv8, 24
  %or10 = or i64 %or6, %shl9
  %arrayidx11 = getelementptr inbounds i8, ptr %ptr, i64 4
  %4 = load i8, ptr %arrayidx11, align 1
  %conv12 = zext i8 %4 to i64
  %shl13 = shl i64 %conv12, 32
  %or14 = or i64 %or10, %shl13
  %arrayidx15 = getelementptr inbounds i8, ptr %ptr, i64 5
  %5 = load i8, ptr %arrayidx15, align 1
  %conv16 = zext i8 %5 to i64
  %shl17 = shl i64 %conv16, 40
  %or18 = or i64 %or14, %shl17
  %arrayidx19 = getelementptr inbounds i8, ptr %ptr, i64 6
  %6 = load i8, ptr %arrayidx19, align 1
  %conv20 = zext i8 %6 to i64
  %shl21 = shl i64 %conv20, 48
  %or22 = or i64 %or18, %shl21
  %arrayidx23 = getelementptr inbounds i8, ptr %ptr, i64 7
  %7 = load i8, ptr %arrayidx23, align 1
  %conv24 = zext i8 %7 to i64
  %shl25 = shl i64 %conv24, 56
  %or26 = or i64 %or22, %shl25
  ret i64 %or26
}

define i32 @loadCombine_4consecutive_metadata(ptr %p, ptr %pstr) {
; LE-LABEL: @loadCombine_4consecutive_metadata(
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1, !alias.scope !0
; LE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias !0
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_metadata(
; 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, !alias.scope !0
; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1, !alias.scope !0
; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1, !alias.scope !0
; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1, !alias.scope !0
; BE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias !0
; 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, !alias.scope !2
  %l2 = load i8, ptr %p1, !alias.scope !2
  %l3 = load i8, ptr %p2, !alias.scope !2
  %l4 = load i8, ptr %p3, !alias.scope !2
  store i32 25, ptr %pstr, !noalias !2

  %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
}

!0 = distinct !{!0}
!1 = distinct !{!1, !0}
!2 = !{!1}

; CHECK: !0 = !{!1}
; CHECK: !1 = distinct !{!1, !2}
; CHECK: !2 = distinct !{!2}

define i16 @loadCombine_4consecutive_4bit(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_4bit(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i4, ptr [[P:%.*]], i32 1
; ALL-NEXT:    [[P2:%.*]] = getelementptr i4, ptr [[P]], i32 2
; ALL-NEXT:    [[P3:%.*]] = getelementptr i4, ptr [[P]], i32 3
; ALL-NEXT:    [[L1:%.*]] = load i4, ptr [[P]], align 1
; ALL-NEXT:    [[L2:%.*]] = load i4, ptr [[P1]], align 1
; ALL-NEXT:    [[L3:%.*]] = load i4, ptr [[P2]], align 1
; ALL-NEXT:    [[L4:%.*]] = load i4, ptr [[P3]], align 1
; ALL-NEXT:    [[E1:%.*]] = zext i4 [[L1]] to i16
; ALL-NEXT:    [[E2:%.*]] = zext i4 [[L2]] to i16
; ALL-NEXT:    [[E3:%.*]] = zext i4 [[L3]] to i16
; ALL-NEXT:    [[E4:%.*]] = zext i4 [[L4]] to i16
; ALL-NEXT:    [[S2:%.*]] = shl i16 [[E2]], 4
; ALL-NEXT:    [[S3:%.*]] = shl i16 [[E3]], 8
; ALL-NEXT:    [[S4:%.*]] = shl i16 [[E4]], 12
; ALL-NEXT:    [[O1:%.*]] = or i16 [[E1]], [[S2]]
; ALL-NEXT:    [[O2:%.*]] = or i16 [[O1]], [[S3]]
; ALL-NEXT:    [[O3:%.*]] = or i16 [[O2]], [[S4]]
; ALL-NEXT:    ret i16 [[O3]]
;
  %p1 = getelementptr i4, ptr %p, i32 1
  %p2 = getelementptr i4, ptr %p, i32 2
  %p3 = getelementptr i4, ptr %p, i32 3
  %l1 = load i4, ptr %p
  %l2 = load i4, ptr %p1
  %l3 = load i4, ptr %p2
  %l4 = load i4, ptr %p3
  %e1 = zext i4 %l1 to i16
  %e2 = zext i4 %l2 to i16
  %e3 = zext i4 %l3 to i16
  %e4 = zext i4 %l4 to i16
  %s2 = shl i16 %e2, 4
  %s3 = shl i16 %e3, 8
  %s4 = shl i16 %e4, 12
  %o1 = or i16 %e1, %s2
  %o2 = or i16 %o1, %s3
  %o3 = or i16 %o2, %s4
  ret i16 %o3
}

define i32 @loadCombine_4consecutive_rev(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_rev(
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_rev(
; 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 [[S4]], [[S3]]
; 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
  %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 %s4, %s3
  %o2 = or i32 %o1, %s2
  %o3 = or i32 %o2, %e1
  ret i32 %o3
}

define i64 @loadCombine_8consecutive_rev(ptr %p) {
; LE-LABEL: @loadCombine_8consecutive_rev(
; LE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 1
; LE-NEXT:    ret i64 [[L1]]
;
; BE-LABEL: @loadCombine_8consecutive_rev(
; 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:    [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 4
; BE-NEXT:    [[P5:%.*]] = getelementptr i8, ptr [[P]], i32 5
; BE-NEXT:    [[P6:%.*]] = getelementptr i8, ptr [[P]], i32 6
; BE-NEXT:    [[P7:%.*]] = getelementptr i8, ptr [[P]], i32 7
; 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:    [[L5:%.*]] = load i8, ptr [[P4]], align 1
; BE-NEXT:    [[L6:%.*]] = load i8, ptr [[P5]], align 1
; BE-NEXT:    [[L7:%.*]] = load i8, ptr [[P6]], align 1
; BE-NEXT:    [[L8:%.*]] = load i8, ptr [[P7]], align 1
; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i64
; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i64
; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i64
; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i64
; BE-NEXT:    [[E5:%.*]] = zext i8 [[L5]] to i64
; BE-NEXT:    [[E6:%.*]] = zext i8 [[L6]] to i64
; BE-NEXT:    [[E7:%.*]] = zext i8 [[L7]] to i64
; BE-NEXT:    [[E8:%.*]] = zext i8 [[L8]] to i64
; BE-NEXT:    [[S2:%.*]] = shl i64 [[E2]], 8
; BE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 16
; BE-NEXT:    [[S4:%.*]] = shl i64 [[E4]], 24
; BE-NEXT:    [[S5:%.*]] = shl i64 [[E5]], 32
; BE-NEXT:    [[S6:%.*]] = shl i64 [[E6]], 40
; BE-NEXT:    [[S7:%.*]] = shl i64 [[E7]], 48
; BE-NEXT:    [[S8:%.*]] = shl i64 [[E8]], 56
; BE-NEXT:    [[O7:%.*]] = or i64 [[S8]], [[S7]]
; BE-NEXT:    [[O6:%.*]] = or i64 [[O7]], [[S6]]
; BE-NEXT:    [[O5:%.*]] = or i64 [[O6]], [[S5]]
; BE-NEXT:    [[O4:%.*]] = or i64 [[O5]], [[S4]]
; BE-NEXT:    [[O3:%.*]] = or i64 [[O4]], [[S3]]
; BE-NEXT:    [[O2:%.*]] = or i64 [[O3]], [[S2]]
; BE-NEXT:    [[O1:%.*]] = or i64 [[O2]], [[E1]]
; BE-NEXT:    ret i64 [[O1]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %p2 = getelementptr i8, ptr %p, i32 2
  %p3 = getelementptr i8, ptr %p, i32 3
  %p4 = getelementptr i8, ptr %p, i32 4
  %p5 = getelementptr i8, ptr %p, i32 5
  %p6 = getelementptr i8, ptr %p, i32 6
  %p7 = getelementptr i8, ptr %p, i32 7
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  %l4 = load i8, ptr %p3
  %l5 = load i8, ptr %p4
  %l6 = load i8, ptr %p5
  %l7 = load i8, ptr %p6
  %l8 = load i8, ptr %p7

  %e1 = zext i8 %l1 to i64
  %e2 = zext i8 %l2 to i64
  %e3 = zext i8 %l3 to i64
  %e4 = zext i8 %l4 to i64
  %e5 = zext i8 %l5 to i64
  %e6 = zext i8 %l6 to i64
  %e7 = zext i8 %l7 to i64
  %e8 = zext i8 %l8 to i64

  %s2 = shl i64 %e2, 8
  %s3 = shl i64 %e3, 16
  %s4 = shl i64 %e4, 24
  %s5 = shl i64 %e5, 32
  %s6 = shl i64 %e6, 40
  %s7 = shl i64 %e7, 48
  %s8 = shl i64 %e8, 56

  %o7 = or i64 %s8, %s7
  %o6 = or i64 %o7, %s6
  %o5 = or i64 %o6, %s5
  %o4 = or i64 %o5, %s4
  %o3 = or i64 %o4, %s3
  %o2 = or i64 %o3, %s2
  %o1 = or i64 %o2, %e1
  ret i64 %o1
}

define i64 @loadCombine_8consecutive_rev_BE(ptr %p) {
; LE-LABEL: @loadCombine_8consecutive_rev_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:    [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 4
; LE-NEXT:    [[P5:%.*]] = getelementptr i8, ptr [[P]], i32 5
; LE-NEXT:    [[P6:%.*]] = getelementptr i8, ptr [[P]], i32 6
; LE-NEXT:    [[P7:%.*]] = getelementptr i8, ptr [[P]], i32 7
; 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:    [[L5:%.*]] = load i8, ptr [[P4]], align 1
; LE-NEXT:    [[L6:%.*]] = load i8, ptr [[P5]], align 1
; LE-NEXT:    [[L7:%.*]] = load i8, ptr [[P6]], align 1
; LE-NEXT:    [[L8:%.*]] = load i8, ptr [[P7]], align 1
; LE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i64
; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i64
; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i64
; LE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i64
; LE-NEXT:    [[E5:%.*]] = zext i8 [[L5]] to i64
; LE-NEXT:    [[E6:%.*]] = zext i8 [[L6]] to i64
; LE-NEXT:    [[E7:%.*]] = zext i8 [[L7]] to i64
; LE-NEXT:    [[E8:%.*]] = zext i8 [[L8]] to i64
; LE-NEXT:    [[S1:%.*]] = shl i64 [[E1]], 56
; LE-NEXT:    [[S2:%.*]] = shl i64 [[E2]], 48
; LE-NEXT:    [[S3:%.*]] = shl i64 [[E3]], 40
; LE-NEXT:    [[S4:%.*]] = shl i64 [[E4]], 32
; LE-NEXT:    [[S5:%.*]] = shl i64 [[E5]], 24
; LE-NEXT:    [[S6:%.*]] = shl i64 [[E6]], 16
; LE-NEXT:    [[S7:%.*]] = shl i64 [[E7]], 8
; LE-NEXT:    [[O7:%.*]] = or i64 [[E8]], [[S7]]
; LE-NEXT:    [[O6:%.*]] = or i64 [[O7]], [[S6]]
; LE-NEXT:    [[O5:%.*]] = or i64 [[O6]], [[S5]]
; LE-NEXT:    [[O4:%.*]] = or i64 [[O5]], [[S4]]
; LE-NEXT:    [[O3:%.*]] = or i64 [[O4]], [[S3]]
; LE-NEXT:    [[O2:%.*]] = or i64 [[O3]], [[S2]]
; LE-NEXT:    [[O1:%.*]] = or i64 [[O2]], [[S1]]
; LE-NEXT:    ret i64 [[O1]]
;
; BE-LABEL: @loadCombine_8consecutive_rev_BE(
; BE-NEXT:    [[L1:%.*]] = load i64, ptr [[P:%.*]], align 1
; BE-NEXT:    ret i64 [[L1]]
;
  %p1 = getelementptr i8, ptr %p, i32 1
  %p2 = getelementptr i8, ptr %p, i32 2
  %p3 = getelementptr i8, ptr %p, i32 3
  %p4 = getelementptr i8, ptr %p, i32 4
  %p5 = getelementptr i8, ptr %p, i32 5
  %p6 = getelementptr i8, ptr %p, i32 6
  %p7 = getelementptr i8, ptr %p, i32 7
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  %l4 = load i8, ptr %p3
  %l5 = load i8, ptr %p4
  %l6 = load i8, ptr %p5
  %l7 = load i8, ptr %p6
  %l8 = load i8, ptr %p7

  %e1 = zext i8 %l1 to i64
  %e2 = zext i8 %l2 to i64
  %e3 = zext i8 %l3 to i64
  %e4 = zext i8 %l4 to i64
  %e5 = zext i8 %l5 to i64
  %e6 = zext i8 %l6 to i64
  %e7 = zext i8 %l7 to i64
  %e8 = zext i8 %l8 to i64

  %s1 = shl i64 %e1, 56
  %s2 = shl i64 %e2, 48
  %s3 = shl i64 %e3, 40
  %s4 = shl i64 %e4, 32
  %s5 = shl i64 %e5, 24
  %s6 = shl i64 %e6, 16
  %s7 = shl i64 %e7, 8

  %o7 = or i64 %e8, %s7
  %o6 = or i64 %o7, %s6
  %o5 = or i64 %o6, %s5
  %o4 = or i64 %o5, %s4
  %o3 = or i64 %o4, %s3
  %o2 = or i64 %o3, %s2
  %o1 = or i64 %o2, %s1
  ret i64 %o1
}

define i64 @eggs(ptr noundef readonly %arg) {
; LE-LABEL: @eggs(
; LE-NEXT:    [[TMP3:%.*]] = load i64, ptr [[ARG:%.*]], align 1
; LE-NEXT:    ret i64 [[TMP3]]
;
; BE-LABEL: @eggs(
; BE-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARG:%.*]], align 1
; BE-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 1
; BE-NEXT:    [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1
; BE-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2
; BE-NEXT:    [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; BE-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 3
; BE-NEXT:    [[TMP9:%.*]] = load i8, ptr [[TMP8]], align 1
; BE-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 4
; BE-NEXT:    [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; BE-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 5
; BE-NEXT:    [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 1
; BE-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 6
; BE-NEXT:    [[TMP15:%.*]] = load i8, ptr [[TMP14]], align 1
; BE-NEXT:    [[TMP16:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 7
; BE-NEXT:    [[TMP17:%.*]] = load i8, ptr [[TMP16]], align 1
; BE-NEXT:    [[TMP18:%.*]] = zext i8 [[TMP17]] to i64
; BE-NEXT:    [[TMP19:%.*]] = shl nuw i64 [[TMP18]], 56
; BE-NEXT:    [[TMP20:%.*]] = zext i8 [[TMP15]] to i64
; BE-NEXT:    [[TMP21:%.*]] = shl nuw nsw i64 [[TMP20]], 48
; BE-NEXT:    [[TMP22:%.*]] = or i64 [[TMP19]], [[TMP21]]
; BE-NEXT:    [[TMP23:%.*]] = zext i8 [[TMP13]] to i64
; BE-NEXT:    [[TMP24:%.*]] = shl nuw nsw i64 [[TMP23]], 40
; BE-NEXT:    [[TMP25:%.*]] = or i64 [[TMP22]], [[TMP24]]
; BE-NEXT:    [[TMP26:%.*]] = zext i8 [[TMP11]] to i64
; BE-NEXT:    [[TMP27:%.*]] = shl nuw nsw i64 [[TMP26]], 32
; BE-NEXT:    [[TMP28:%.*]] = or i64 [[TMP25]], [[TMP27]]
; BE-NEXT:    [[TMP29:%.*]] = zext i8 [[TMP9]] to i64
; BE-NEXT:    [[TMP30:%.*]] = shl nuw nsw i64 [[TMP29]], 24
; BE-NEXT:    [[TMP31:%.*]] = or i64 [[TMP28]], [[TMP30]]
; BE-NEXT:    [[TMP32:%.*]] = zext i8 [[TMP7]] to i64
; BE-NEXT:    [[TMP33:%.*]] = shl nuw nsw i64 [[TMP32]], 16
; BE-NEXT:    [[TMP34:%.*]] = zext i8 [[TMP5]] to i64
; BE-NEXT:    [[TMP35:%.*]] = shl nuw nsw i64 [[TMP34]], 8
; BE-NEXT:    [[TMP36:%.*]] = or i64 [[TMP31]], [[TMP33]]
; BE-NEXT:    [[TMP37:%.*]] = zext i8 [[TMP3]] to i64
; BE-NEXT:    [[TMP38:%.*]] = or i64 [[TMP36]], [[TMP35]]
; BE-NEXT:    [[TMP39:%.*]] = or i64 [[TMP38]], [[TMP37]]
; BE-NEXT:    ret i64 [[TMP39]]
;
  %tmp3 = load i8, ptr %arg, align 1
  %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1
  %tmp5 = load i8, ptr %tmp4, align 1
  %tmp6 = getelementptr inbounds i8, ptr %arg, i64 2
  %tmp7 = load i8, ptr %tmp6, align 1
  %tmp8 = getelementptr inbounds i8, ptr %arg, i64 3
  %tmp9 = load i8, ptr %tmp8, align 1
  %tmp10 = getelementptr inbounds i8, ptr %arg, i64 4
  %tmp11 = load i8, ptr %tmp10, align 1
  %tmp12 = getelementptr inbounds i8, ptr %arg, i64 5
  %tmp13 = load i8, ptr %tmp12, align 1
  %tmp14 = getelementptr inbounds i8, ptr %arg, i64 6
  %tmp15 = load i8, ptr %tmp14, align 1
  %tmp16 = getelementptr inbounds i8, ptr %arg, i64 7
  %tmp17 = load i8, ptr %tmp16, align 1
  %tmp18 = zext i8 %tmp17 to i64
  %tmp19 = shl nuw i64 %tmp18, 56
  %tmp20 = zext i8 %tmp15 to i64
  %tmp21 = shl nuw nsw i64 %tmp20, 48
  %tmp22 = or i64 %tmp19, %tmp21
  %tmp23 = zext i8 %tmp13 to i64
  %tmp24 = shl nuw nsw i64 %tmp23, 40
  %tmp25 = or i64 %tmp22, %tmp24
  %tmp26 = zext i8 %tmp11 to i64
  %tmp27 = shl nuw nsw i64 %tmp26, 32
  %tmp28 = or i64 %tmp25, %tmp27
  %tmp29 = zext i8 %tmp9 to i64
  %tmp30 = shl nuw nsw i64 %tmp29, 24
  %tmp31 = or i64 %tmp28, %tmp30
  %tmp32 = zext i8 %tmp7 to i64
  %tmp33 = shl nuw nsw i64 %tmp32, 16
  %tmp34 = zext i8 %tmp5 to i64
  %tmp35 = shl nuw nsw i64 %tmp34, 8
  %tmp36 = or i64 %tmp31, %tmp33
  %tmp37 = zext i8 %tmp3 to i64
  %tmp38 = or i64 %tmp36, %tmp35
  %tmp39 = or i64 %tmp38, %tmp37
  ret i64 %tmp39
}

define i32 @loadCombine_4consecutive_mixsize1(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_mixsize1(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 3
; ALL-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT:    [[E1:%.*]] = zext i16 [[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]], 16
; ALL-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 24
; ALL-NEXT:    [[O1:%.*]] = or i32 [[E1]], [[S2]]
; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
; ALL-NEXT:    ret i32 [[O2]]
;
  %p1 = getelementptr i8, ptr %p, i32 2
  %p2 = getelementptr i8, ptr %p, i32 3
  %l1 = load i16, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2

  %e1 = zext i16 %l1 to i32
  %e2 = zext i8 %l2 to i32
  %e3 = zext i8 %l3 to i32

  %s2 = shl i32 %e2, 16
  %s3 = shl i32 %e3, 24

  %o1 = or i32 %e1, %s2
  %o2 = or i32 %o1, %s3
  ret i32 %o2
}

define i32 @loadCombine_4consecutive_mixsize1_BE(ptr %p) {
; ALL-LABEL: @loadCombine_4consecutive_mixsize1_BE(
; ALL-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; ALL-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 3
; ALL-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
; ALL-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
; ALL-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i32
; ALL-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; ALL-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
; ALL-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 16
; ALL-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
; ALL-NEXT:    [[O1:%.*]] = or i32 [[S1]], [[S2]]
; ALL-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[E3]]
; ALL-NEXT:    ret i32 [[O2]]
;
  %p1 = getelementptr i8, ptr %p, i32 2
  %p2 = getelementptr i8, ptr %p, i32 3
  %l1 = load i16, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2

  %e1 = zext i16 %l1 to i32
  %e2 = zext i8 %l2 to i32
  %e3 = zext i8 %l3 to i32

  %s1 = shl i32 %e1, 16
  %s2 = shl i32 %e2, 8

  %o1 = or i32 %s1, %s2
  %o2 = or i32 %o1, %e3
  ret i32 %o2
}

define i32 @loadCombine_4consecutive_rev_mixsize1(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_rev_mixsize1(
; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; LE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
; LE-NEXT:    [[L2:%.*]] = load i16, ptr [[P2]], align 1
; LE-NEXT:    [[TMP1:%.*]] = zext i16 [[L2]] to i32
; LE-NEXT:    [[TMP2:%.*]] = shl i32 [[TMP1]], 16
; LE-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i32
; LE-NEXT:    [[O2:%.*]] = or i32 [[TMP2]], [[E1]]
; LE-NEXT:    ret i32 [[O2]]
;
; BE-LABEL: @loadCombine_4consecutive_rev_mixsize1(
; 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 2
; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P2]], align 1
; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P3]], align 1
; BE-NEXT:    [[E1:%.*]] = zext i16 [[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]], 16
; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 24
; BE-NEXT:    [[O1:%.*]] = or i32 [[S3]], [[S2]]
; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[E1]]
; BE-NEXT:    ret i32 [[O2]]
;
  %p2 = getelementptr i8, ptr %p, i32 2
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i16, ptr %p
  %l2 = load i8, ptr %p2
  %l3 = load i8, ptr %p3

  %e1 = zext i16 %l1 to i32
  %e2 = zext i8 %l2 to i32
  %e3 = zext i8 %l3 to i32

  %s2 = shl i32 %e2, 16
  %s3 = shl i32 %e3, 24

  %o1 = or i32 %s3, %s2
  %o2 = or i32 %o1, %e1
  ret i32 %o2
}

define i32 @loadCombine_4consecutive_rev_mixsize1_BE(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_rev_mixsize1_BE(
; 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 2
; LE-NEXT:    [[L2:%.*]] = load i8, ptr [[P2]], align 1
; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P3]], align 1
; LE-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i32
; LE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; LE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
; LE-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 16
; LE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
; LE-NEXT:    [[O1:%.*]] = or i32 [[E3]], [[S2]]
; LE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S1]]
; LE-NEXT:    ret i32 [[O2]]
;
; BE-LABEL: @loadCombine_4consecutive_rev_mixsize1_BE(
; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; BE-NEXT:    [[L1:%.*]] = load i16, ptr [[P]], align 2
; BE-NEXT:    [[L2:%.*]] = load i16, ptr [[P2]], align 1
; BE-NEXT:    [[TMP1:%.*]] = zext i16 [[L2]] to i32
; BE-NEXT:    [[E1:%.*]] = zext i16 [[L1]] to i32
; BE-NEXT:    [[S1:%.*]] = shl i32 [[E1]], 16
; BE-NEXT:    [[O2:%.*]] = or i32 [[TMP1]], [[S1]]
; BE-NEXT:    ret i32 [[O2]]
;
  %p2 = getelementptr i8, ptr %p, i32 2
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i16, ptr %p
  %l2 = load i8, ptr %p2
  %l3 = load i8, ptr %p3

  %e1 = zext i16 %l1 to i32
  %e2 = zext i8 %l2 to i32
  %e3 = zext i8 %l3 to i32

  %s1 = shl i32 %e1, 16
  %s2 = shl i32 %e2, 8

  %o1 = or i32 %e3, %s2
  %o2 = or i32 %o1, %s1
  ret i32 %o2
}

define i32 @loadCombine_4consecutive_mixsize2(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_mixsize2(
; 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 i16, ptr [[P2]], align 2
; LE-NEXT:    [[E3:%.*]] = zext i16 [[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_4consecutive_mixsize2(
; 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 i16, ptr [[P2]], align 2
; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; BE-NEXT:    [[E3:%.*]] = zext i16 [[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
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  %l3 = load i16, ptr %p2

  %e1 = zext i8 %l1 to i32
  %e2 = zext i8 %l2 to i32
  %e3 = zext i16 %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
}

define i32 @loadCombine_4consecutive_lower_index_comes_before(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_lower_index_comes_before(
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_lower_index_comes_before(
; 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:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l4 = load i8, ptr %p3
  %l3 = load i8, ptr %p2
  %l2 = load i8, ptr %p1
  %l1 = load i8, ptr %p

  %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 i16 @loadCombine_2consecutive_badinsert(ptr %p) {
; 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
  store i8 0, ptr %p1, align 1
  %l1 = load i8, ptr %p
  %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 i32 @loadCombine_4consecutive_badinsert(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_badinsert(
; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 1
; LE-NEXT:    store i8 0, ptr [[P1]], align 1
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_badinsert(
; 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:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
; BE-NEXT:    store i8 0, ptr [[P1]], 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l2 = load i8, ptr %p1
  %l3 = load i8, ptr %p2
  store i8 0, ptr %p1, align 1
  %l4 = load i8, ptr %p3
  %l1 = load i8, ptr %p

  %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_badinsert2(ptr %p) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l2 = load i8, ptr %p1
  store i8 0, ptr %p3, align 1
  %l3 = load i8, ptr %p2
  %l4 = load i8, ptr %p3
  %l1 = load i8, ptr %p

  %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_badinsert3(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_badinsert3(
; LE-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[TMP1]], align 1
; LE-NEXT:    ret i32 [[L1]]
;
; BE-LABEL: @loadCombine_4consecutive_badinsert3(
; BE-NEXT:    [[P4:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 4
; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P4]], align 1
; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
; BE-NEXT:    [[S4:%.*]] = shl i32 [[E4]], 24
; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P3]], align 1
; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
; BE-NEXT:    [[S3:%.*]] = shl i32 [[E3]], 16
; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P2]], align 1
; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; BE-NEXT:    [[S2:%.*]] = shl i32 [[E2]], 8
; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P]], i32 1
; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P1]], align 1
; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
; 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]]
;
  %p4 = getelementptr i8, ptr %p, i32 4
  %l4 = load i8, ptr %p4
  %e4 = zext i8 %l4 to i32
  %s4 = shl i32 %e4, 24

  %p3 = getelementptr i8, ptr %p, i32 3
  %l3 = load i8, ptr %p3
  %e3 = zext i8 %l3 to i32
  %s3 = shl i32 %e3, 16

  %p2 = getelementptr i8, ptr %p, i32 2
  %l2 = load i8, ptr %p2
  %e2 = zext i8 %l2 to i32
  %s2 = shl i32 %e2, 8

  %p1 = getelementptr i8, ptr %p, i32 1
  %l1 = load i8, ptr %p1
  %e1 = zext i8 %l1 to i32

  %o1 = or i32 %e1, %s2
  %o2 = or i32 %o1, %s3
  %o3 = or i32 %o2, %s4
  ret i32 %o3
}

define i32 @loadCombine_4consecutive_badinsert4(ptr %p) {
; LE-LABEL: @loadCombine_4consecutive_badinsert4(
; LE-NEXT:  entry:
; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
; LE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
; LE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
; LE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
; LE:       bb2:
; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P1]], align 1
; LE-NEXT:    br label [[END]]
; LE:       end:
; LE-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[L1]], [[BB2]] ]
; LE-NEXT:    ret i32 [[COND]]
;
; BE-LABEL: @loadCombine_4consecutive_badinsert4(
; BE-NEXT:  entry:
; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
; BE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
; BE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
; BE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
; BE:       bb2:
; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P1]], align 1
; BE-NEXT:    [[C2:%.*]] = zext i8 [[L1]] to i32
; BE-NEXT:    [[P4:%.*]] = getelementptr i8, ptr [[P]], i64 4
; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P4]], align 1
; BE-NEXT:    [[E4:%.*]] = zext i8 [[L4]] to i32
; BE-NEXT:    [[S4:%.*]] = shl nuw i32 [[E4]], 24
; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P3]], align 1
; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
; BE-NEXT:    [[S3:%.*]] = shl nuw nsw i32 [[E3]], 16
; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P2]], align 1
; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
; BE-NEXT:    [[S2:%.*]] = shl nuw nsw i32 [[E2]], 8
; BE-NEXT:    [[O1:%.*]] = or i32 [[S2]], [[C2]]
; BE-NEXT:    [[O2:%.*]] = or i32 [[O1]], [[S3]]
; BE-NEXT:    [[O3:%.*]] = or i32 [[O2]], [[S4]]
; BE-NEXT:    br label [[END]]
; BE:       end:
; BE-NEXT:    [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[O3]], [[BB2]] ]
; BE-NEXT:    ret i32 [[COND]]
;
entry:
  %p1 = getelementptr i8, ptr %p, i64 1
  %c1 = load i8, ptr %p1, align 1
  %cmp = icmp eq i8 %c1, 0
  br i1 %cmp, label %end, label %bb2

bb2:
  %l1 = load i8, ptr %p1, align 1
  %c2 = zext i8 %l1 to i32
  %p4 = getelementptr i8, ptr %p, i64 4
  %l4 = load i8, ptr %p4, align 1
  %e4 = zext i8 %l4 to i32
  %s4 = shl nuw i32 %e4, 24
  %p3 = getelementptr i8, ptr %p, i64 3
  %l3 = load i8, ptr %p3, align 1
  %e3 = zext i8 %l3 to i32
  %s3 = shl nuw nsw i32 %e3, 16
  %p2 = getelementptr i8, ptr %p, i64 2
  %l2 = load i8, ptr %p2, align 1
  %e2 = zext i8 %l2 to i32
  %s2 = shl nuw nsw i32 %e2, 8
  %o1 = or i32 %s2, %c2
  %o2 = or i32 %o1, %s3
  %o3 = or i32 %o2, %s4
  br label %end

end:
  %cond = phi i32 [ 0, %entry ], [ %o3, %bb2 ]
  ret i32 %cond
}

define i32 @loadCombine_4consecutive_badinsert5(ptr %p) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l4 = load i8, ptr %p3
  store i8 0, ptr %p2, align 1
  %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
  %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_badinsert6(ptr %p) {
; 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
  %p3 = getelementptr i8, ptr %p, i32 3
  %l1 = load i8, ptr %p
  %l2 = load i8, ptr %p1
  store i8 0, ptr %p3, align 1
  %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 %s3, %s4
  %o2 = or i32 %o1, %s2
  %o3 = or i32 %o2, %e1
  ret i32 %o3
}

define i64 @loadCombine_nonConstShift1(ptr %arg, i8 %b) {
; ALL-LABEL: @loadCombine_nonConstShift1(
; ALL-NEXT:    [[G1:%.*]] = getelementptr i8, ptr [[ARG:%.*]], i64 1
; ALL-NEXT:    [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
; ALL-NEXT:    [[LD1:%.*]] = load i8, ptr [[G1]], align 1
; ALL-NEXT:    [[Z0:%.*]] = zext i8 [[LD0]] to i64
; ALL-NEXT:    [[Z1:%.*]] = zext i8 [[LD1]] to i64
; ALL-NEXT:    [[Z6:%.*]] = zext i8 [[B:%.*]] to i64
; ALL-NEXT:    [[S0:%.*]] = shl i64 [[Z0]], [[Z6]]
; ALL-NEXT:    [[S1:%.*]] = shl i64 [[Z1]], 8
; ALL-NEXT:    [[O7:%.*]] = or i64 [[S0]], [[S1]]
; ALL-NEXT:    ret i64 [[O7]]
;
  %g1 = getelementptr i8, ptr %arg, i64 1
  %ld0 = load i8, ptr %arg, align 1
  %ld1 = load i8, ptr %g1, align 1
  %z0 = zext i8 %ld0 to i64
  %z1 = zext i8 %ld1 to i64
  %z6 = zext i8 %b to i64
  %s0 = shl i64 %z0, %z6
  %s1 = shl i64 %z1, 8
  %o7 = or i64 %s0, %s1
  ret i64 %o7
}

define i64 @loadCombine_nonConstShift2(ptr %arg, i8 %b) {
; ALL-LABEL: @loadCombine_nonConstShift2(
; ALL-NEXT:    [[G1:%.*]] = getelementptr i8, ptr [[ARG:%.*]], i64 1
; ALL-NEXT:    [[LD0:%.*]] = load i8, ptr [[ARG]], align 1
; ALL-NEXT:    [[LD1:%.*]] = load i8, ptr [[G1]], align 1
; ALL-NEXT:    [[Z0:%.*]] = zext i8 [[LD0]] to i64
; ALL-NEXT:    [[Z1:%.*]] = zext i8 [[LD1]] to i64
; ALL-NEXT:    [[Z6:%.*]] = zext i8 [[B:%.*]] to i64
; ALL-NEXT:    [[S0:%.*]] = shl i64 [[Z0]], [[Z6]]
; ALL-NEXT:    [[S1:%.*]] = shl i64 [[Z1]], 8
; ALL-NEXT:    [[O7:%.*]] = or i64 [[S1]], [[S0]]
; ALL-NEXT:    ret i64 [[O7]]
;
  %g1 = getelementptr i8, ptr %arg, i64 1
  %ld0 = load i8, ptr %arg, align 1
  %ld1 = load i8, ptr %g1, align 1
  %z0 = zext i8 %ld0 to i64
  %z1 = zext i8 %ld1 to i64
  %z6 = zext i8 %b to i64
  %s0 = shl i64 %z0, %z6
  %s1 = shl i64 %z1, 8
  %o7 = or i64 %s1, %s0
  ret i64 %o7
}

define void @nested_gep(ptr %p, ptr %dest) {
; LE-LABEL: @nested_gep(
; LE-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 68
; LE-NEXT:    [[LD2:%.*]] = load i64, ptr [[TMP1]], align 4
; LE-NEXT:    [[TRUNC:%.*]] = trunc i64 [[LD2]] to i32
; LE-NEXT:    store i32 [[TRUNC]], ptr [[DEST:%.*]], align 4
; LE-NEXT:    ret void
;
; BE-LABEL: @nested_gep(
; BE-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 72
; BE-NEXT:    [[LD1:%.*]] = load i32, ptr [[GEP1]], align 4
; BE-NEXT:    [[LD1_ZEXT:%.*]] = zext i32 [[LD1]] to i64
; BE-NEXT:    [[LD1_SHL:%.*]] = shl nuw i64 [[LD1_ZEXT]], 32
; BE-NEXT:    [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 64
; BE-NEXT:    [[FINAL_PTR:%.*]] = getelementptr inbounds i8, ptr [[GEP2]], i64 4
; BE-NEXT:    [[LD2:%.*]] = load i32, ptr [[FINAL_PTR]], align 4
; BE-NEXT:    [[LD2_ZEXT:%.*]] = zext i32 [[LD2]] to i64
; BE-NEXT:    [[OR:%.*]] = or i64 [[LD1_SHL]], [[LD2_ZEXT]]
; BE-NEXT:    [[ADD:%.*]] = add i64 [[OR]], 0
; BE-NEXT:    [[TRUNC:%.*]] = trunc i64 [[ADD]] to i32
; BE-NEXT:    store i32 [[TRUNC]], ptr [[DEST:%.*]], align 4
; BE-NEXT:    ret void
;
  %gep1 = getelementptr inbounds i8, ptr %p, i64 72
  %ld1 = load i32, ptr %gep1, align 4
  %ld1_zext = zext i32 %ld1 to i64
  %ld1_shl = shl nuw i64 %ld1_zext, 32
  %gep2 = getelementptr inbounds i8, ptr %p, i64 64
  ; Don't move final_ptr before gep2
  %final_ptr = getelementptr inbounds i8, ptr %gep2, i64 4
  %ld2 = load i32, ptr %final_ptr, align 4
  %ld2_zext = zext i32 %ld2 to i64
  %or = or i64 %ld1_shl, %ld2_zext
  %add = add i64 %or, 0
  %trunc = trunc i64 %add to i32
  store i32 %trunc, ptr %dest, align 4
  ret void
}


define void @bitcast_gep(ptr %p, ptr %dest) {
; LE-LABEL: @bitcast_gep(
; LE-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 68
; LE-NEXT:    [[LD2:%.*]] = load i64, ptr [[TMP1]], align 4
; LE-NEXT:    [[TRUNC:%.*]] = trunc i64 [[LD2]] to i32
; LE-NEXT:    store i32 [[TRUNC]], ptr [[DEST:%.*]], align 4
; LE-NEXT:    ret void
;
; BE-LABEL: @bitcast_gep(
; BE-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 72
; BE-NEXT:    [[LD1:%.*]] = load i32, ptr [[GEP1]], align 4
; BE-NEXT:    [[LD1_ZEXT:%.*]] = zext i32 [[LD1]] to i64
; BE-NEXT:    [[LD1_SHL:%.*]] = shl nuw i64 [[LD1_ZEXT]], 32
; BE-NEXT:    [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 68
; BE-NEXT:    [[FINAL_PTR:%.*]] = bitcast ptr [[GEP2]] to ptr
; BE-NEXT:    [[LD2:%.*]] = load i32, ptr [[FINAL_PTR]], align 4
; BE-NEXT:    [[LD2_ZEXT:%.*]] = zext i32 [[LD2]] to i64
; BE-NEXT:    [[OR:%.*]] = or i64 [[LD1_SHL]], [[LD2_ZEXT]]
; BE-NEXT:    [[ADD:%.*]] = add i64 [[OR]], 0
; BE-NEXT:    [[TRUNC:%.*]] = trunc i64 [[ADD]] to i32
; BE-NEXT:    store i32 [[TRUNC]], ptr [[DEST:%.*]], align 4
; BE-NEXT:    ret void
;
  %gep1 = getelementptr inbounds i8, ptr %p, i64 72
  %ld1 = load i32, ptr %gep1, align 4
  %ld1_zext = zext i32 %ld1 to i64
  %ld1_shl = shl nuw i64 %ld1_zext, 32
  %gep2 = getelementptr inbounds i8, ptr %p, i64 68
  ; Don't move final_ptr before gep2
  %final_ptr = bitcast ptr %gep2 to ptr
  %ld2 = load i32, ptr %final_ptr, align 4
  %ld2_zext = zext i32 %ld2 to i64
  %or = or i64 %ld1_shl, %ld2_zext
  %add = add i64 %or, 0
  %trunc = trunc i64 %add to i32
  store i32 %trunc, ptr %dest, align 4
  ret void
}