| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s | |
| %v8i8 = type { i8, i8, i8, i8, i8, i8, i8, i8 } | |
| ; https://bugs.llvm.org/show_bug.cgi?id=43146 | |
| define i64 @load_bswap(ptr %p) { | |
| ; CHECK-LABEL: @load_bswap( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[P:%.*]], align 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 | |
| ; CHECK-NEXT: [[OR01234567:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]]) | |
| ; CHECK-NEXT: ret i64 [[OR01234567]] | |
| ; | |
| %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 | |
| %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 | |
| %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 | |
| %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 | |
| %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 | |
| %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 | |
| %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 | |
| %t0 = load i8, ptr %p | |
| %t1 = load i8, ptr %g1 | |
| %t2 = load i8, ptr %g2 | |
| %t3 = load i8, ptr %g3 | |
| %t4 = load i8, ptr %g4 | |
| %t5 = load i8, ptr %g5 | |
| %t6 = load i8, ptr %g6 | |
| %t7 = load i8, ptr %g7 | |
| %z0 = zext i8 %t0 to i64 | |
| %z1 = zext i8 %t1 to i64 | |
| %z2 = zext i8 %t2 to i64 | |
| %z3 = zext i8 %t3 to i64 | |
| %z4 = zext i8 %t4 to i64 | |
| %z5 = zext i8 %t5 to i64 | |
| %z6 = zext i8 %t6 to i64 | |
| %z7 = zext i8 %t7 to i64 | |
| %sh0 = shl nuw i64 %z0, 56 | |
| %sh1 = shl nuw nsw i64 %z1, 48 | |
| %sh2 = shl nuw nsw i64 %z2, 40 | |
| %sh3 = shl nuw nsw i64 %z3, 32 | |
| %sh4 = shl nuw nsw i64 %z4, 24 | |
| %sh5 = shl nuw nsw i64 %z5, 16 | |
| %sh6 = shl nuw nsw i64 %z6, 8 | |
| ; %sh7 = shl nuw nsw i64 %z7, 0 <-- missing phantom shift | |
| %or01 = or i64 %sh0, %sh1 | |
| %or012 = or i64 %or01, %sh2 | |
| %or0123 = or i64 %or012, %sh3 | |
| %or01234 = or i64 %or0123, %sh4 | |
| %or012345 = or i64 %or01234, %sh5 | |
| %or0123456 = or i64 %or012345, %sh6 | |
| %or01234567 = or i64 %or0123456, %z7 | |
| ret i64 %or01234567 | |
| } | |
| define i64 @load_bswap_nop_shift(ptr %p) { | |
| ; CHECK-LABEL: @load_bswap_nop_shift( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[P:%.*]], align 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 | |
| ; CHECK-NEXT: [[OR01234567:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]]) | |
| ; CHECK-NEXT: ret i64 [[OR01234567]] | |
| ; | |
| %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 | |
| %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 | |
| %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 | |
| %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 | |
| %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 | |
| %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 | |
| %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 | |
| %t0 = load i8, ptr %p | |
| %t1 = load i8, ptr %g1 | |
| %t2 = load i8, ptr %g2 | |
| %t3 = load i8, ptr %g3 | |
| %t4 = load i8, ptr %g4 | |
| %t5 = load i8, ptr %g5 | |
| %t6 = load i8, ptr %g6 | |
| %t7 = load i8, ptr %g7 | |
| %z0 = zext i8 %t0 to i64 | |
| %z1 = zext i8 %t1 to i64 | |
| %z2 = zext i8 %t2 to i64 | |
| %z3 = zext i8 %t3 to i64 | |
| %z4 = zext i8 %t4 to i64 | |
| %z5 = zext i8 %t5 to i64 | |
| %z6 = zext i8 %t6 to i64 | |
| %z7 = zext i8 %t7 to i64 | |
| %sh0 = shl nuw i64 %z0, 56 | |
| %sh1 = shl nuw nsw i64 %z1, 48 | |
| %sh2 = shl nuw nsw i64 %z2, 40 | |
| %sh3 = shl nuw nsw i64 %z3, 32 | |
| %sh4 = shl nuw nsw i64 %z4, 24 | |
| %sh5 = shl nuw nsw i64 %z5, 16 | |
| %sh6 = shl nuw nsw i64 %z6, 8 | |
| %sh7 = shl nuw nsw i64 %z7, 0 | |
| %or01 = or i64 %sh0, %sh1 | |
| %or012 = or i64 %or01, %sh2 | |
| %or0123 = or i64 %or012, %sh3 | |
| %or01234 = or i64 %or0123, %sh4 | |
| %or012345 = or i64 %or01234, %sh5 | |
| %or0123456 = or i64 %or012345, %sh6 | |
| %or01234567 = or i64 %or0123456, %sh7 | |
| ret i64 %or01234567 | |
| } | |
| ; https://bugs.llvm.org/show_bug.cgi?id=42708 | |
| define i64 @load64le(ptr %arg) { | |
| ; CHECK-LABEL: @load64le( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[ARG:%.*]], align 1 | |
| ; CHECK-NEXT: [[O7:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 | |
| ; CHECK-NEXT: ret i64 [[O7]] | |
| ; | |
| %g1 = getelementptr inbounds i8, ptr %arg, i64 1 | |
| %g2 = getelementptr inbounds i8, ptr %arg, i64 2 | |
| %g3 = getelementptr inbounds i8, ptr %arg, i64 3 | |
| %g4 = getelementptr inbounds i8, ptr %arg, i64 4 | |
| %g5 = getelementptr inbounds i8, ptr %arg, i64 5 | |
| %g6 = getelementptr inbounds i8, ptr %arg, i64 6 | |
| %g7 = getelementptr inbounds i8, ptr %arg, i64 7 | |
| %ld0 = load i8, ptr %arg, align 1 | |
| %ld1 = load i8, ptr %g1, align 1 | |
| %ld2 = load i8, ptr %g2, align 1 | |
| %ld3 = load i8, ptr %g3, align 1 | |
| %ld4 = load i8, ptr %g4, align 1 | |
| %ld5 = load i8, ptr %g5, align 1 | |
| %ld6 = load i8, ptr %g6, align 1 | |
| %ld7 = load i8, ptr %g7, align 1 | |
| %z0 = zext i8 %ld0 to i64 | |
| %z1 = zext i8 %ld1 to i64 | |
| %z2 = zext i8 %ld2 to i64 | |
| %z3 = zext i8 %ld3 to i64 | |
| %z4 = zext i8 %ld4 to i64 | |
| %z5 = zext i8 %ld5 to i64 | |
| %z6 = zext i8 %ld6 to i64 | |
| %z7 = zext i8 %ld7 to i64 | |
| ; %s0 = shl nuw nsw i64 %z0, 0 <-- missing phantom shift | |
| %s1 = shl nuw nsw i64 %z1, 8 | |
| %s2 = shl nuw nsw i64 %z2, 16 | |
| %s3 = shl nuw nsw i64 %z3, 24 | |
| %s4 = shl nuw nsw i64 %z4, 32 | |
| %s5 = shl nuw nsw i64 %z5, 40 | |
| %s6 = shl nuw nsw i64 %z6, 48 | |
| %s7 = shl nuw i64 %z7, 56 | |
| %o1 = or i64 %s1, %z0 | |
| %o2 = or i64 %o1, %s2 | |
| %o3 = or i64 %o2, %s3 | |
| %o4 = or i64 %o3, %s4 | |
| %o5 = or i64 %o4, %s5 | |
| %o6 = or i64 %o5, %s6 | |
| %o7 = or i64 %o6, %s7 | |
| ret i64 %o7 | |
| } | |
| define i64 @load64le_nop_shift(ptr %arg) { | |
| ; CHECK-LABEL: @load64le_nop_shift( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[ARG:%.*]], align 1 | |
| ; CHECK-NEXT: [[O7:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 | |
| ; CHECK-NEXT: ret i64 [[O7]] | |
| ; | |
| %g1 = getelementptr inbounds i8, ptr %arg, i64 1 | |
| %g2 = getelementptr inbounds i8, ptr %arg, i64 2 | |
| %g3 = getelementptr inbounds i8, ptr %arg, i64 3 | |
| %g4 = getelementptr inbounds i8, ptr %arg, i64 4 | |
| %g5 = getelementptr inbounds i8, ptr %arg, i64 5 | |
| %g6 = getelementptr inbounds i8, ptr %arg, i64 6 | |
| %g7 = getelementptr inbounds i8, ptr %arg, i64 7 | |
| %ld0 = load i8, ptr %arg, align 1 | |
| %ld1 = load i8, ptr %g1, align 1 | |
| %ld2 = load i8, ptr %g2, align 1 | |
| %ld3 = load i8, ptr %g3, align 1 | |
| %ld4 = load i8, ptr %g4, align 1 | |
| %ld5 = load i8, ptr %g5, align 1 | |
| %ld6 = load i8, ptr %g6, align 1 | |
| %ld7 = load i8, ptr %g7, align 1 | |
| %z0 = zext i8 %ld0 to i64 | |
| %z1 = zext i8 %ld1 to i64 | |
| %z2 = zext i8 %ld2 to i64 | |
| %z3 = zext i8 %ld3 to i64 | |
| %z4 = zext i8 %ld4 to i64 | |
| %z5 = zext i8 %ld5 to i64 | |
| %z6 = zext i8 %ld6 to i64 | |
| %z7 = zext i8 %ld7 to i64 | |
| %s0 = shl nuw nsw i64 %z0, 0 | |
| %s1 = shl nuw nsw i64 %z1, 8 | |
| %s2 = shl nuw nsw i64 %z2, 16 | |
| %s3 = shl nuw nsw i64 %z3, 24 | |
| %s4 = shl nuw nsw i64 %z4, 32 | |
| %s5 = shl nuw nsw i64 %z5, 40 | |
| %s6 = shl nuw nsw i64 %z6, 48 | |
| %s7 = shl nuw i64 %z7, 56 | |
| %o1 = or i64 %s1, %s0 | |
| %o2 = or i64 %o1, %s2 | |
| %o3 = or i64 %o2, %s3 | |
| %o4 = or i64 %o3, %s4 | |
| %o5 = or i64 %o4, %s5 | |
| %o6 = or i64 %o5, %s6 | |
| %o7 = or i64 %o6, %s7 | |
| ret i64 %o7 | |
| } | |
| define i64 @load_bswap_disjoint(ptr %p) { | |
| ; CHECK-LABEL: @load_bswap_disjoint( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[P:%.*]], align 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP1]]) | |
| ; CHECK-NEXT: ret i64 [[TMP2]] | |
| ; | |
| %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 | |
| %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 | |
| %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 | |
| %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 | |
| %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 | |
| %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 | |
| %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 | |
| %t0 = load i8, ptr %p | |
| %t1 = load i8, ptr %g1 | |
| %t2 = load i8, ptr %g2 | |
| %t3 = load i8, ptr %g3 | |
| %t4 = load i8, ptr %g4 | |
| %t5 = load i8, ptr %g5 | |
| %t6 = load i8, ptr %g6 | |
| %t7 = load i8, ptr %g7 | |
| %z0 = zext i8 %t0 to i64 | |
| %z1 = zext i8 %t1 to i64 | |
| %z2 = zext i8 %t2 to i64 | |
| %z3 = zext i8 %t3 to i64 | |
| %z4 = zext i8 %t4 to i64 | |
| %z5 = zext i8 %t5 to i64 | |
| %z6 = zext i8 %t6 to i64 | |
| %z7 = zext i8 %t7 to i64 | |
| %sh0 = shl nuw i64 %z0, 56 | |
| %sh1 = shl nuw nsw i64 %z1, 48 | |
| %sh2 = shl nuw nsw i64 %z2, 40 | |
| %sh3 = shl nuw nsw i64 %z3, 32 | |
| %sh4 = shl nuw nsw i64 %z4, 24 | |
| %sh5 = shl nuw nsw i64 %z5, 16 | |
| %sh6 = shl nuw nsw i64 %z6, 8 | |
| ; %sh7 = shl nuw nsw i64 %z7, 0 <-- missing phantom shift | |
| %or01 = or disjoint i64 %sh0, %sh1 | |
| %or012 = or disjoint i64 %or01, %sh2 | |
| %or0123 = or disjoint i64 %or012, %sh3 | |
| %or01234 = or disjoint i64 %or0123, %sh4 | |
| %or012345 = or disjoint i64 %or01234, %sh5 | |
| %or0123456 = or disjoint i64 %or012345, %sh6 | |
| %or01234567 = or disjoint i64 %or0123456, %z7 | |
| ret i64 %or01234567 | |
| } | |
| define i64 @load_bswap_nop_shift_disjoint(ptr %p) { | |
| ; CHECK-LABEL: @load_bswap_nop_shift_disjoint( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[P:%.*]], align 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP1]]) | |
| ; CHECK-NEXT: ret i64 [[TMP2]] | |
| ; | |
| %g1 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 1 | |
| %g2 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 2 | |
| %g3 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 3 | |
| %g4 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 4 | |
| %g5 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 5 | |
| %g6 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 6 | |
| %g7 = getelementptr inbounds %v8i8, ptr %p, i64 0, i32 7 | |
| %t0 = load i8, ptr %p | |
| %t1 = load i8, ptr %g1 | |
| %t2 = load i8, ptr %g2 | |
| %t3 = load i8, ptr %g3 | |
| %t4 = load i8, ptr %g4 | |
| %t5 = load i8, ptr %g5 | |
| %t6 = load i8, ptr %g6 | |
| %t7 = load i8, ptr %g7 | |
| %z0 = zext i8 %t0 to i64 | |
| %z1 = zext i8 %t1 to i64 | |
| %z2 = zext i8 %t2 to i64 | |
| %z3 = zext i8 %t3 to i64 | |
| %z4 = zext i8 %t4 to i64 | |
| %z5 = zext i8 %t5 to i64 | |
| %z6 = zext i8 %t6 to i64 | |
| %z7 = zext i8 %t7 to i64 | |
| %sh0 = shl nuw i64 %z0, 56 | |
| %sh1 = shl nuw nsw i64 %z1, 48 | |
| %sh2 = shl nuw nsw i64 %z2, 40 | |
| %sh3 = shl nuw nsw i64 %z3, 32 | |
| %sh4 = shl nuw nsw i64 %z4, 24 | |
| %sh5 = shl nuw nsw i64 %z5, 16 | |
| %sh6 = shl nuw nsw i64 %z6, 8 | |
| %sh7 = shl nuw nsw i64 %z7, 0 | |
| %or01 = or disjoint i64 %sh0, %sh1 | |
| %or012 = or disjoint i64 %or01, %sh2 | |
| %or0123 = or disjoint i64 %or012, %sh3 | |
| %or01234 = or disjoint i64 %or0123, %sh4 | |
| %or012345 = or disjoint i64 %or01234, %sh5 | |
| %or0123456 = or disjoint i64 %or012345, %sh6 | |
| %or01234567 = or disjoint i64 %or0123456, %sh7 | |
| ret i64 %or01234567 | |
| } | |
| define i64 @load64le_disjoint(ptr %arg) { | |
| ; CHECK-LABEL: @load64le_disjoint( | |
| ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 1 | |
| ; CHECK-NEXT: ret i64 [[TMP2]] | |
| ; | |
| %g1 = getelementptr inbounds i8, ptr %arg, i64 1 | |
| %g2 = getelementptr inbounds i8, ptr %arg, i64 2 | |
| %g3 = getelementptr inbounds i8, ptr %arg, i64 3 | |
| %g4 = getelementptr inbounds i8, ptr %arg, i64 4 | |
| %g5 = getelementptr inbounds i8, ptr %arg, i64 5 | |
| %g6 = getelementptr inbounds i8, ptr %arg, i64 6 | |
| %g7 = getelementptr inbounds i8, ptr %arg, i64 7 | |
| %ld0 = load i8, ptr %arg, align 1 | |
| %ld1 = load i8, ptr %g1, align 1 | |
| %ld2 = load i8, ptr %g2, align 1 | |
| %ld3 = load i8, ptr %g3, align 1 | |
| %ld4 = load i8, ptr %g4, align 1 | |
| %ld5 = load i8, ptr %g5, align 1 | |
| %ld6 = load i8, ptr %g6, align 1 | |
| %ld7 = load i8, ptr %g7, align 1 | |
| %z0 = zext i8 %ld0 to i64 | |
| %z1 = zext i8 %ld1 to i64 | |
| %z2 = zext i8 %ld2 to i64 | |
| %z3 = zext i8 %ld3 to i64 | |
| %z4 = zext i8 %ld4 to i64 | |
| %z5 = zext i8 %ld5 to i64 | |
| %z6 = zext i8 %ld6 to i64 | |
| %z7 = zext i8 %ld7 to i64 | |
| ; %s0 = shl nuw nsw i64 %z0, 0 <-- missing phantom shift | |
| %s1 = shl nuw nsw i64 %z1, 8 | |
| %s2 = shl nuw nsw i64 %z2, 16 | |
| %s3 = shl nuw nsw i64 %z3, 24 | |
| %s4 = shl nuw nsw i64 %z4, 32 | |
| %s5 = shl nuw nsw i64 %z5, 40 | |
| %s6 = shl nuw nsw i64 %z6, 48 | |
| %s7 = shl nuw i64 %z7, 56 | |
| %o1 = or disjoint i64 %s1, %z0 | |
| %o2 = or disjoint i64 %o1, %s2 | |
| %o3 = or disjoint i64 %o2, %s3 | |
| %o4 = or disjoint i64 %o3, %s4 | |
| %o5 = or disjoint i64 %o4, %s5 | |
| %o6 = or disjoint i64 %o5, %s6 | |
| %o7 = or disjoint i64 %o6, %s7 | |
| ret i64 %o7 | |
| } | |
| define i64 @load64le_nop_shift_disjoint(ptr %arg) { | |
| ; CHECK-LABEL: @load64le_nop_shift_disjoint( | |
| ; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 1 | |
| ; CHECK-NEXT: ret i64 [[TMP2]] | |
| ; | |
| %g1 = getelementptr inbounds i8, ptr %arg, i64 1 | |
| %g2 = getelementptr inbounds i8, ptr %arg, i64 2 | |
| %g3 = getelementptr inbounds i8, ptr %arg, i64 3 | |
| %g4 = getelementptr inbounds i8, ptr %arg, i64 4 | |
| %g5 = getelementptr inbounds i8, ptr %arg, i64 5 | |
| %g6 = getelementptr inbounds i8, ptr %arg, i64 6 | |
| %g7 = getelementptr inbounds i8, ptr %arg, i64 7 | |
| %ld0 = load i8, ptr %arg, align 1 | |
| %ld1 = load i8, ptr %g1, align 1 | |
| %ld2 = load i8, ptr %g2, align 1 | |
| %ld3 = load i8, ptr %g3, align 1 | |
| %ld4 = load i8, ptr %g4, align 1 | |
| %ld5 = load i8, ptr %g5, align 1 | |
| %ld6 = load i8, ptr %g6, align 1 | |
| %ld7 = load i8, ptr %g7, align 1 | |
| %z0 = zext i8 %ld0 to i64 | |
| %z1 = zext i8 %ld1 to i64 | |
| %z2 = zext i8 %ld2 to i64 | |
| %z3 = zext i8 %ld3 to i64 | |
| %z4 = zext i8 %ld4 to i64 | |
| %z5 = zext i8 %ld5 to i64 | |
| %z6 = zext i8 %ld6 to i64 | |
| %z7 = zext i8 %ld7 to i64 | |
| %s0 = shl nuw nsw i64 %z0, 0 | |
| %s1 = shl nuw nsw i64 %z1, 8 | |
| %s2 = shl nuw nsw i64 %z2, 16 | |
| %s3 = shl nuw nsw i64 %z3, 24 | |
| %s4 = shl nuw nsw i64 %z4, 32 | |
| %s5 = shl nuw nsw i64 %z5, 40 | |
| %s6 = shl nuw nsw i64 %z6, 48 | |
| %s7 = shl nuw i64 %z7, 56 | |
| %o1 = or disjoint i64 %s1, %s0 | |
| %o2 = or disjoint i64 %o1, %s2 | |
| %o3 = or disjoint i64 %o2, %s3 | |
| %o4 = or disjoint i64 %o3, %s4 | |
| %o5 = or disjoint i64 %o4, %s5 | |
| %o6 = or disjoint i64 %o5, %s6 | |
| %o7 = or disjoint i64 %o6, %s7 | |
| ret i64 %o7 | |
| } | |
| define void @PR39538(ptr %t0, ptr %t1) { | |
| ; CHECK-LABEL: @PR39538( | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, ptr [[T0:%.*]], align 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i32> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 1, i32 5, i32 9, i32 13> | |
| ; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> | |
| ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 2, i32 6, i32 10, i32 14> | |
| ; CHECK-NEXT: [[TMP7:%.*]] = zext <4 x i8> [[TMP6]] to <4 x i32> | |
| ; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <16 x i8> [[TMP1]], <16 x i8> poison, <4 x i32> <i32 3, i32 7, i32 11, i32 15> | |
| ; CHECK-NEXT: [[TMP9:%.*]] = zext <4 x i8> [[TMP8]] to <4 x i32> | |
| ; CHECK-NEXT: [[TMP10:%.*]] = shl nuw <4 x i32> [[TMP3]], splat (i32 24) | |
| ; CHECK-NEXT: [[TMP11:%.*]] = shl nuw nsw <4 x i32> [[TMP5]], splat (i32 16) | |
| ; CHECK-NEXT: [[TMP12:%.*]] = shl nuw nsw <4 x i32> [[TMP7]], splat (i32 8) | |
| ; CHECK-NEXT: [[TMP13:%.*]] = or <4 x i32> [[TMP11]], [[TMP10]] | |
| ; CHECK-NEXT: [[TMP14:%.*]] = or <4 x i32> [[TMP13]], [[TMP12]] | |
| ; CHECK-NEXT: [[TMP15:%.*]] = or <4 x i32> [[TMP14]], [[TMP9]] | |
| ; CHECK-NEXT: store <4 x i32> [[TMP15]], ptr [[T1:%.*]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %t6 = getelementptr inbounds i8, ptr %t0, i64 1 | |
| %t11 = getelementptr inbounds i8, ptr %t0, i64 2 | |
| %t16 = getelementptr inbounds i8, ptr %t0, i64 3 | |
| %t20 = getelementptr inbounds i8, ptr %t0, i64 4 | |
| %t24 = getelementptr inbounds i8, ptr %t0, i64 5 | |
| %t29 = getelementptr inbounds i8, ptr %t0, i64 6 | |
| %t34 = getelementptr inbounds i8, ptr %t0, i64 7 | |
| %t39 = getelementptr inbounds i8, ptr %t0, i64 8 | |
| %t43 = getelementptr inbounds i8, ptr %t0, i64 9 | |
| %t48 = getelementptr inbounds i8, ptr %t0, i64 10 | |
| %t53 = getelementptr inbounds i8, ptr %t0, i64 11 | |
| %t58 = getelementptr inbounds i8, ptr %t0, i64 12 | |
| %t62 = getelementptr inbounds i8, ptr %t0, i64 13 | |
| %t67 = getelementptr inbounds i8, ptr %t0, i64 14 | |
| %t72 = getelementptr inbounds i8, ptr %t0, i64 15 | |
| %t38 = getelementptr inbounds i32, ptr %t1, i64 1 | |
| %t57 = getelementptr inbounds i32, ptr %t1, i64 2 | |
| %t76 = getelementptr inbounds i32, ptr %t1, i64 3 | |
| %t3 = load i8, ptr %t0, align 1 | |
| %t7 = load i8, ptr %t6, align 1 | |
| %t12 = load i8, ptr %t11, align 1 | |
| %t17 = load i8, ptr %t16, align 1 | |
| %t21 = load i8, ptr %t20, align 1 | |
| %t25 = load i8, ptr %t24, align 1 | |
| %t30 = load i8, ptr %t29, align 1 | |
| %t35 = load i8, ptr %t34, align 1 | |
| %t40 = load i8, ptr %t39, align 1 | |
| %t44 = load i8, ptr %t43, align 1 | |
| %t49 = load i8, ptr %t48, align 1 | |
| %t54 = load i8, ptr %t53, align 1 | |
| %t59 = load i8, ptr %t58, align 1 | |
| %t63 = load i8, ptr %t62, align 1 | |
| %t68 = load i8, ptr %t67, align 1 | |
| %t73 = load i8, ptr %t72, align 1 | |
| %t4 = zext i8 %t3 to i32 | |
| %t8 = zext i8 %t7 to i32 | |
| %t13 = zext i8 %t12 to i32 | |
| %t18 = zext i8 %t17 to i32 | |
| %t22 = zext i8 %t21 to i32 | |
| %t26 = zext i8 %t25 to i32 | |
| %t31 = zext i8 %t30 to i32 | |
| %t36 = zext i8 %t35 to i32 | |
| %t41 = zext i8 %t40 to i32 | |
| %t45 = zext i8 %t44 to i32 | |
| %t50 = zext i8 %t49 to i32 | |
| %t55 = zext i8 %t54 to i32 | |
| %t60 = zext i8 %t59 to i32 | |
| %t64 = zext i8 %t63 to i32 | |
| %t69 = zext i8 %t68 to i32 | |
| %t74 = zext i8 %t73 to i32 | |
| %t5 = shl nuw i32 %t4, 24 | |
| %t23 = shl nuw i32 %t22, 24 | |
| %t42 = shl nuw i32 %t41, 24 | |
| %t61 = shl nuw i32 %t60, 24 | |
| %t9 = shl nuw nsw i32 %t8, 16 | |
| %t27 = shl nuw nsw i32 %t26, 16 | |
| %t46 = shl nuw nsw i32 %t45, 16 | |
| %t65 = shl nuw nsw i32 %t64, 16 | |
| %t14 = shl nuw nsw i32 %t13, 8 | |
| %t32 = shl nuw nsw i32 %t31, 8 | |
| %t51 = shl nuw nsw i32 %t50, 8 | |
| %t70 = shl nuw nsw i32 %t69, 8 | |
| %t10 = or i32 %t9, %t5 | |
| %t15 = or i32 %t10, %t14 | |
| %t19 = or i32 %t15, %t18 | |
| %t28 = or i32 %t27, %t23 | |
| %t33 = or i32 %t28, %t32 | |
| %t37 = or i32 %t33, %t36 | |
| %t47 = or i32 %t46, %t42 | |
| %t52 = or i32 %t47, %t51 | |
| %t56 = or i32 %t52, %t55 | |
| %t66 = or i32 %t65, %t61 | |
| %t71 = or i32 %t66, %t70 | |
| %t75 = or i32 %t71, %t74 | |
| store i32 %t19, ptr %t1, align 4 | |
| store i32 %t37, ptr %t38, align 4 | |
| store i32 %t56, ptr %t57, align 4 | |
| store i32 %t75, ptr %t76, align 4 | |
| ret void | |
| } | |
| ; Do not crash on constant expressions. | |
| @g1 = external dso_local unnamed_addr constant [8 x i8], align 1 | |
| @g2 = external dso_local unnamed_addr constant [5 x i8], align 1 | |
| define void @load_combine_constant_expression(ptr %t1) { | |
| ; CHECK-LABEL: @load_combine_constant_expression( | |
| ; CHECK-NEXT: [[EXT1:%.*]] = zext i32 ptrtoint (ptr @g1 to i32) to i64 | |
| ; CHECK-NEXT: [[EXT2:%.*]] = zext i32 ptrtoint (ptr @g2 to i32) to i64 | |
| ; CHECK-NEXT: [[SHL1:%.*]] = shl i64 [[EXT1]], 32 | |
| ; CHECK-NEXT: [[OR1:%.*]] = or i64 [[SHL1]], [[EXT2]] | |
| ; CHECK-NEXT: store i64 [[OR1]], ptr [[T1:%.*]], align 4 | |
| ; CHECK-NEXT: [[T3:%.*]] = getelementptr i64, ptr [[T1]], i64 1 | |
| ; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[EXT1]], 32 | |
| ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[SHL2]], [[EXT2]] | |
| ; CHECK-NEXT: store i64 [[OR2]], ptr [[T3]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %ext1 = zext i32 ptrtoint (ptr @g1 to i32) to i64 | |
| %ext2 = zext i32 ptrtoint (ptr @g2 to i32) to i64 | |
| %shl1 = shl i64 %ext1, 32 | |
| %or1 = or i64 %shl1, %ext2 | |
| store i64 %or1, ptr %t1, align 4 | |
| %t3 = getelementptr i64, ptr %t1, i64 1 | |
| %shl2 = shl i64 %ext1, 32 | |
| %or2 = or i64 %shl2, %ext2 | |
| store i64 %or2, ptr %t3, align 4 | |
| ret void | |
| } | |
| @output = dso_local local_unnamed_addr global [8 x i32] zeroinitializer, align 16 | |
| define void @PR47450(ptr nocapture readonly %p) { | |
| ; CHECK-LABEL: @PR47450( | |
| ; CHECK-NEXT: [[X:%.*]] = load i16, ptr [[P:%.*]], align 2 | |
| ; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X]] to i32 | |
| ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 1 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[S]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: store <4 x i32> [[TMP2]], ptr @output, align 16 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %x = load i16, ptr %p, align 2 | |
| %z = zext i16 %x to i32 | |
| %s = shl nuw nsw i32 %z, 1 | |
| store i32 %s, ptr @output, align 16 | |
| store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 1), align 4 | |
| store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 2), align 8 | |
| store i32 %s, ptr getelementptr inbounds ([8 x i32], ptr @output, i64 0, i64 3), align 4 | |
| ret void | |
| } |