| ; 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, 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) { |
| ; 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, 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) { |
| ; 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, 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) { |
| ; 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, 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) { |
| ; 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, 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) { |
| ; 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: [[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) { |
| ; 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 |
| } |