bipmis e9393789a9 [AggressiveInstCombine] Handle the insert point of the merged load correctly.
This patch updates the load insert point of the merged load in AggressiveInstCombine().
This is done to handle the reported test breaks by handling Alias Analysis correctly.

Differential Revision: https://reviews.llvm.org/D137201
2022-11-29 10:53:51 +00:00

2088 lines
74 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple aarch64 -data-layout="e-n64" | FileCheck %s --check-prefixes=ALL,LE
; RUN: opt < %s -passes=aggressive-instcombine -S -mtriple aarch64 -data-layout="E-n64" | FileCheck %s --check-prefixes=ALL,BE
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]]
;
%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) {
; 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]]
;
%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, i8* %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, i8* %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) {
; 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]]
;
%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, i8* %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) {
; 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]]
;
%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, i8* %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) {
; 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]]
;
%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, i8* %p3
store i8 5, i8* %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) {
; 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]]
;
%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, i8* %p3
store i8 5, i8* %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, i8* %ps
%l2 = load i8, ptr %p1
store i8 10, i8* %ps1
%l3 = load i8, ptr %p2
store i8 10, i8* %ps2
%l4 = load i8, ptr %p3
store i8 10, i8* %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) {
; 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]]
;
%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) {
; ALL-LABEL: @loadCombine_4consecutive_rev_mixsize1(
; ALL-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; ALL-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
; ALL-NEXT: [[L1:%.*]] = load i16, ptr [[P]], align 2
; ALL-NEXT: [[L2:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT: [[L3:%.*]] = load i8, ptr [[P3]], 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 [[S3]], [[S2]]
; ALL-NEXT: [[O2:%.*]] = or i32 [[O1]], [[E1]]
; ALL-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) {
; ALL-LABEL: @loadCombine_4consecutive_rev_mixsize1_BE(
; ALL-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 2
; ALL-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
; ALL-NEXT: [[L1:%.*]] = load i16, ptr [[P]], align 2
; ALL-NEXT: [[L2:%.*]] = load i8, ptr [[P2]], align 1
; ALL-NEXT: [[L3:%.*]] = load i8, ptr [[P3]], 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 [[E3]], [[S2]]
; ALL-NEXT: [[O2:%.*]] = or i32 [[O1]], [[S1]]
; ALL-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) {
; ALL-LABEL: @loadCombine_4consecutive_mixsize2(
; 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 i16, ptr [[P2]], align 2
; ALL-NEXT: [[E1:%.*]] = zext i8 [[L1]] to i32
; ALL-NEXT: [[E2:%.*]] = zext i8 [[L2]] to i32
; ALL-NEXT: [[E3:%.*]] = zext i16 [[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]]
;
%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) {
; 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]]
;
%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) {
; 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]]
;
%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: [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
; LE-NEXT: [[L1:%.*]] = load i32, ptr [[P1]], 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) {
; 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]]
;
%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) {
; 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]]
;
%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
}