blob: 9accfb60c806c41cbcc519403e9de4242c3cf017 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=slp-vectorizer -S < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64-v3 | FileCheck %s
; The buildvector of the reduced values is emitted in the loop and is executed
; on every iteration, as the reduction itself.
define i32 @gather_root_xor_reduction(ptr %w, ptr %t) {
; CHECK-LABEL: define i32 @gather_root_xor_reduction(
; CHECK-SAME: ptr [[W:%.*]], ptr [[T:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; CHECK-NEXT: [[CRC:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[LOOP]] ]
; CHECK-NEXT: [[CRC_EXT:%.*]] = zext i32 [[CRC]] to i64
; CHECK-NEXT: [[W_P:%.*]] = getelementptr inbounds i64, ptr [[W]], i64 [[IV]]
; CHECK-NEXT: [[W_V:%.*]] = load i64, ptr [[W_P]], align 8
; CHECK-NEXT: [[V:%.*]] = xor i64 [[W_V]], [[CRC_EXT]]
; CHECK-NEXT: [[I0:%.*]] = and i64 [[V]], 255
; CHECK-NEXT: [[S1:%.*]] = lshr i64 [[V]], 8
; CHECK-NEXT: [[I1:%.*]] = and i64 [[S1]], 255
; CHECK-NEXT: [[S2:%.*]] = lshr i64 [[V]], 16
; CHECK-NEXT: [[I2:%.*]] = and i64 [[S2]], 255
; CHECK-NEXT: [[S3:%.*]] = lshr i64 [[V]], 24
; CHECK-NEXT: [[I3:%.*]] = and i64 [[S3]], 255
; CHECK-NEXT: [[S4:%.*]] = lshr i64 [[V]], 32
; CHECK-NEXT: [[I4:%.*]] = and i64 [[S4]], 255
; CHECK-NEXT: [[S5:%.*]] = lshr i64 [[V]], 40
; CHECK-NEXT: [[I5:%.*]] = and i64 [[S5]], 255
; CHECK-NEXT: [[S6:%.*]] = lshr i64 [[V]], 48
; CHECK-NEXT: [[I6:%.*]] = and i64 [[S6]], 255
; CHECK-NEXT: [[I7:%.*]] = lshr i64 [[V]], 56
; CHECK-NEXT: [[P0:%.*]] = getelementptr inbounds i32, ptr [[T]], i64 [[I0]]
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 1, i64 [[I1]]
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 2, i64 [[I2]]
; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 3, i64 [[I3]]
; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 4, i64 [[I4]]
; CHECK-NEXT: [[P5:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 5, i64 [[I5]]
; CHECK-NEXT: [[P6:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 6, i64 [[I6]]
; CHECK-NEXT: [[P7:%.*]] = getelementptr inbounds [256 x i32], ptr [[T]], i64 7, i64 [[I7]]
; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[P0]], align 4
; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[P1]], align 4
; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[P2]], align 4
; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[P3]], align 4
; CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[P4]], align 4
; CHECK-NEXT: [[L5:%.*]] = load i32, ptr [[P5]], align 4
; CHECK-NEXT: [[L6:%.*]] = load i32, ptr [[P6]], align 4
; CHECK-NEXT: [[L7:%.*]] = load i32, ptr [[P7]], align 4
; CHECK-NEXT: [[X1:%.*]] = xor i32 [[L1]], [[L0]]
; CHECK-NEXT: [[X2:%.*]] = xor i32 [[L2]], [[X1]]
; CHECK-NEXT: [[X3:%.*]] = xor i32 [[L3]], [[X2]]
; CHECK-NEXT: [[X4:%.*]] = xor i32 [[L4]], [[X3]]
; CHECK-NEXT: [[X5:%.*]] = xor i32 [[L5]], [[X4]]
; CHECK-NEXT: [[X6:%.*]] = xor i32 [[L6]], [[X5]]
; CHECK-NEXT: [[TMP8]] = xor i32 [[L7]], [[X6]]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
; CHECK-NEXT: br i1 [[CMP]], label %[[EXIT:.*]], label %[[LOOP]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret i32 [[TMP8]]
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%crc = phi i32 [ 0, %entry ], [ %x7, %loop ]
%crc.ext = zext i32 %crc to i64
%w.p = getelementptr inbounds i64, ptr %w, i64 %iv
%w.v = load i64, ptr %w.p, align 8
%v = xor i64 %w.v, %crc.ext
%i0 = and i64 %v, 255
%s1 = lshr i64 %v, 8
%i1 = and i64 %s1, 255
%s2 = lshr i64 %v, 16
%i2 = and i64 %s2, 255
%s3 = lshr i64 %v, 24
%i3 = and i64 %s3, 255
%s4 = lshr i64 %v, 32
%i4 = and i64 %s4, 255
%s5 = lshr i64 %v, 40
%i5 = and i64 %s5, 255
%s6 = lshr i64 %v, 48
%i6 = and i64 %s6, 255
%i7 = lshr i64 %v, 56
%p0 = getelementptr inbounds i32, ptr %t, i64 %i0
%p1 = getelementptr inbounds [256 x i32], ptr %t, i64 1, i64 %i1
%p2 = getelementptr inbounds [256 x i32], ptr %t, i64 2, i64 %i2
%p3 = getelementptr inbounds [256 x i32], ptr %t, i64 3, i64 %i3
%p4 = getelementptr inbounds [256 x i32], ptr %t, i64 4, i64 %i4
%p5 = getelementptr inbounds [256 x i32], ptr %t, i64 5, i64 %i5
%p6 = getelementptr inbounds [256 x i32], ptr %t, i64 6, i64 %i6
%p7 = getelementptr inbounds [256 x i32], ptr %t, i64 7, i64 %i7
%l0 = load i32, ptr %p0, align 4
%l1 = load i32, ptr %p1, align 4
%l2 = load i32, ptr %p2, align 4
%l3 = load i32, ptr %p3, align 4
%l4 = load i32, ptr %p4, align 4
%l5 = load i32, ptr %p5, align 4
%l6 = load i32, ptr %p6, align 4
%l7 = load i32, ptr %p7, align 4
%x1 = xor i32 %l1, %l0
%x2 = xor i32 %l2, %x1
%x3 = xor i32 %l3, %x2
%x4 = xor i32 %l4, %x3
%x5 = xor i32 %l5, %x4
%x6 = xor i32 %l6, %x5
%x7 = xor i32 %l7, %x6
%iv.next = add nuw nsw i64 %iv, 1
%cmp = icmp eq i64 %iv.next, 1024
br i1 %cmp, label %exit, label %loop
exit:
ret i32 %x7
}