; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt < %s -passes="default" -S -mattr=+sse2 | FileCheck %s ; RUN: opt < %s -passes="default" -S -mattr=+avx | FileCheck %s ; RUN: opt < %s -passes="default" -S -mattr=+avx2 | FileCheck %s ; RUN: opt < %s -passes="default" -S -mattr=+avx512f | FileCheck %s ; RUN: opt < %s -passes="default" -S -mattr=+avx512bw | FileCheck %s @a = dso_local global [1024 x i8] zeroinitializer, align 16 @b = dso_local global [1024 x i8] zeroinitializer, align 16 define dso_local i32 @sad_16i8() #0 { ; CHECK-LABEL: define dso_local i32 @sad_16i8( ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <16 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[I10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw i8, ptr @a, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[I]], align 16 ; CHECK-NEXT: [[I2:%.*]] = zext <16 x i8> [[WIDE_LOAD]] to <16 x i32> ; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw i8, ptr @b, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <16 x i8>, ptr [[I3]], align 16 ; CHECK-NEXT: [[I5:%.*]] = zext <16 x i8> [[WIDE_LOAD1]] to <16 x i32> ; CHECK-NEXT: [[I6:%.*]] = sub nsw <16 x i32> [[I2]], [[I5]] ; CHECK-NEXT: [[I9:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[I6]], i1 true) ; CHECK-NEXT: [[I10]] = add nuw nsw <16 x i32> [[I9]], [[VEC_PHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw nsw i64 [[INDEX]], 16 ; CHECK-NEXT: [[I11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 ; CHECK-NEXT: br i1 [[I11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: [[I12:%.*]] = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[I10]]) ; CHECK-NEXT: ret i32 [[I12]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] %vec.phi = phi <16 x i32> [ zeroinitializer, %entry ], [ %i10, %vector.body ] %i = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index %i1 = bitcast ptr %i to ptr %wide.load = load <16 x i8>, ptr %i1, align 4 %i2 = zext <16 x i8> %wide.load to <16 x i32> %i3 = getelementptr inbounds [1024 x i8], ptr @b, i64 0, i64 %index %i4 = bitcast ptr %i3 to ptr %wide.load1 = load <16 x i8>, ptr %i4, align 4 %i5 = zext <16 x i8> %wide.load1 to <16 x i32> %i6 = sub nsw <16 x i32> %i2, %i5 %i7 = icmp sgt <16 x i32> %i6, splat (i32 -1) %i8 = sub nsw <16 x i32> zeroinitializer, %i6 %i9 = select <16 x i1> %i7, <16 x i32> %i6, <16 x i32> %i8 %i10 = add nsw <16 x i32> %i9, %vec.phi %index.next = add i64 %index, 16 %i11 = icmp eq i64 %index.next, 1024 br i1 %i11, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %rdx.shuf = shufflevector <16 x i32> %i10, <16 x i32> undef, <16 x i32> %bin.rdx = add <16 x i32> %i10, %rdx.shuf %rdx.shuf2 = shufflevector <16 x i32> %bin.rdx, <16 x i32> undef, <16 x i32> %bin.rdx2 = add <16 x i32> %bin.rdx, %rdx.shuf2 %rdx.shuf3 = shufflevector <16 x i32> %bin.rdx2, <16 x i32> undef, <16 x i32> %bin.rdx3 = add <16 x i32> %bin.rdx2, %rdx.shuf3 %rdx.shuf4 = shufflevector <16 x i32> %bin.rdx3, <16 x i32> undef, <16 x i32> %bin.rdx4 = add <16 x i32> %bin.rdx3, %rdx.shuf4 %i12 = extractelement <16 x i32> %bin.rdx4, i32 0 ret i32 %i12 } define dso_local i32 @sad_32i8() #0 { ; CHECK-LABEL: define dso_local i32 @sad_32i8( ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <32 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[I10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw i8, ptr @a, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <32 x i8>, ptr [[I]], align 32 ; CHECK-NEXT: [[I2:%.*]] = zext <32 x i8> [[WIDE_LOAD]] to <32 x i32> ; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw i8, ptr @b, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <32 x i8>, ptr [[I3]], align 32 ; CHECK-NEXT: [[I5:%.*]] = zext <32 x i8> [[WIDE_LOAD1]] to <32 x i32> ; CHECK-NEXT: [[I6:%.*]] = sub nsw <32 x i32> [[I2]], [[I5]] ; CHECK-NEXT: [[I9:%.*]] = tail call <32 x i32> @llvm.abs.v32i32(<32 x i32> [[I6]], i1 true) ; CHECK-NEXT: [[I10]] = add nuw nsw <32 x i32> [[I9]], [[VEC_PHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw nsw i64 [[INDEX]], 32 ; CHECK-NEXT: [[I11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 ; CHECK-NEXT: br i1 [[I11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: [[I12:%.*]] = tail call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> [[I10]]) ; CHECK-NEXT: ret i32 [[I12]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] %vec.phi = phi <32 x i32> [ zeroinitializer, %entry ], [ %i10, %vector.body ] %i = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index %i1 = bitcast ptr %i to ptr %wide.load = load <32 x i8>, ptr %i1, align 32 %i2 = zext <32 x i8> %wide.load to <32 x i32> %i3 = getelementptr inbounds [1024 x i8], ptr @b, i64 0, i64 %index %i4 = bitcast ptr %i3 to ptr %wide.load1 = load <32 x i8>, ptr %i4, align 32 %i5 = zext <32 x i8> %wide.load1 to <32 x i32> %i6 = sub nsw <32 x i32> %i2, %i5 %i7 = icmp sgt <32 x i32> %i6, splat (i32 -1) %i8 = sub nsw <32 x i32> zeroinitializer, %i6 %i9 = select <32 x i1> %i7, <32 x i32> %i6, <32 x i32> %i8 %i10 = add nsw <32 x i32> %i9, %vec.phi %index.next = add i64 %index, 32 %i11 = icmp eq i64 %index.next, 1024 br i1 %i11, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %rdx.shuf = shufflevector <32 x i32> %i10, <32 x i32> undef, <32 x i32> %bin.rdx = add <32 x i32> %i10, %rdx.shuf %rdx.shuf2 = shufflevector <32 x i32> %bin.rdx, <32 x i32> undef, <32 x i32> %bin.rdx2 = add <32 x i32> %bin.rdx, %rdx.shuf2 %rdx.shuf3 = shufflevector <32 x i32> %bin.rdx2, <32 x i32> undef, <32 x i32> %bin.rdx3 = add <32 x i32> %bin.rdx2, %rdx.shuf3 %rdx.shuf4 = shufflevector <32 x i32> %bin.rdx3, <32 x i32> undef, <32 x i32> %bin.rdx4 = add <32 x i32> %bin.rdx3, %rdx.shuf4 %rdx.shuf5 = shufflevector <32 x i32> %bin.rdx4, <32 x i32> undef, <32 x i32> %bin.rdx5 = add <32 x i32> %bin.rdx4, %rdx.shuf5 %i12 = extractelement <32 x i32> %bin.rdx5, i32 0 ret i32 %i12 } define dso_local i32 @sad_avx64i8() #0 { ; CHECK-LABEL: define dso_local i32 @sad_avx64i8( ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <64 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[I10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw i8, ptr @a, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <64 x i8>, ptr [[I]], align 64 ; CHECK-NEXT: [[I2:%.*]] = zext <64 x i8> [[WIDE_LOAD]] to <64 x i32> ; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw i8, ptr @b, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <64 x i8>, ptr [[I3]], align 64 ; CHECK-NEXT: [[I5:%.*]] = zext <64 x i8> [[WIDE_LOAD1]] to <64 x i32> ; CHECK-NEXT: [[I6:%.*]] = sub nsw <64 x i32> [[I2]], [[I5]] ; CHECK-NEXT: [[I9:%.*]] = tail call <64 x i32> @llvm.abs.v64i32(<64 x i32> [[I6]], i1 true) ; CHECK-NEXT: [[I10]] = add nuw nsw <64 x i32> [[I9]], [[VEC_PHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw nsw i64 [[INDEX]], 64 ; CHECK-NEXT: [[I11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 ; CHECK-NEXT: br i1 [[I11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: [[I12:%.*]] = tail call i32 @llvm.vector.reduce.add.v64i32(<64 x i32> [[I10]]) ; CHECK-NEXT: ret i32 [[I12]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] %vec.phi = phi <64 x i32> [ zeroinitializer, %entry ], [ %i10, %vector.body ] %i = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index %i1 = bitcast ptr %i to ptr %wide.load = load <64 x i8>, ptr %i1, align 64 %i2 = zext <64 x i8> %wide.load to <64 x i32> %i3 = getelementptr inbounds [1024 x i8], ptr @b, i64 0, i64 %index %i4 = bitcast ptr %i3 to ptr %wide.load1 = load <64 x i8>, ptr %i4, align 64 %i5 = zext <64 x i8> %wide.load1 to <64 x i32> %i6 = sub nsw <64 x i32> %i2, %i5 %i7 = icmp sgt <64 x i32> %i6, splat (i32 -1) %i8 = sub nsw <64 x i32> zeroinitializer, %i6 %i9 = select <64 x i1> %i7, <64 x i32> %i6, <64 x i32> %i8 %i10 = add nsw <64 x i32> %i9, %vec.phi %index.next = add i64 %index, 64 %i11 = icmp eq i64 %index.next, 1024 br i1 %i11, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %rdx.shuf = shufflevector <64 x i32> %i10, <64 x i32> undef, <64 x i32> %bin.rdx = add <64 x i32> %i10, %rdx.shuf %rdx.shuf2 = shufflevector <64 x i32> %bin.rdx, <64 x i32> undef, <64 x i32> %bin.rdx2 = add <64 x i32> %bin.rdx, %rdx.shuf2 %rdx.shuf3 = shufflevector <64 x i32> %bin.rdx2, <64 x i32> undef, <64 x i32> %bin.rdx3 = add <64 x i32> %bin.rdx2, %rdx.shuf3 %rdx.shuf4 = shufflevector <64 x i32> %bin.rdx3, <64 x i32> undef, <64 x i32> %bin.rdx4 = add <64 x i32> %bin.rdx3, %rdx.shuf4 %rdx.shuf5 = shufflevector <64 x i32> %bin.rdx4, <64 x i32> undef, <64 x i32> %bin.rdx5 = add <64 x i32> %bin.rdx4, %rdx.shuf5 %rdx.shuf6 = shufflevector <64 x i32> %bin.rdx5, <64 x i32> undef, <64 x i32> %bin.rdx6 = add <64 x i32> %bin.rdx5, %rdx.shuf6 %i12 = extractelement <64 x i32> %bin.rdx6, i32 0 ret i32 %i12 } define dso_local i32 @sad_2i8() #0 { ; CHECK-LABEL: define dso_local i32 @sad_2i8( ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[I10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw i8, ptr @a, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i8>, ptr [[I]], align 4 ; CHECK-NEXT: [[I2:%.*]] = zext <2 x i8> [[WIDE_LOAD]] to <2 x i32> ; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw i8, ptr @b, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <2 x i8>, ptr [[I3]], align 4 ; CHECK-NEXT: [[I5:%.*]] = zext <2 x i8> [[WIDE_LOAD1]] to <2 x i32> ; CHECK-NEXT: [[I6:%.*]] = sub nsw <2 x i32> [[I2]], [[I5]] ; CHECK-NEXT: [[I9:%.*]] = tail call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[I6]], i1 true) ; CHECK-NEXT: [[I10]] = add nuw nsw <2 x i32> [[I9]], [[VEC_PHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw nsw i64 [[INDEX]], 2 ; CHECK-NEXT: [[I11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 ; CHECK-NEXT: br i1 [[I11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: [[I12:%.*]] = tail call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> [[I10]]) ; CHECK-NEXT: ret i32 [[I12]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] %vec.phi = phi <2 x i32> [ zeroinitializer, %entry ], [ %i10, %vector.body ] %i = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index %i1 = bitcast ptr %i to ptr %wide.load = load <2 x i8>, ptr %i1, align 4 %i2 = zext <2 x i8> %wide.load to <2 x i32> %i3 = getelementptr inbounds [1024 x i8], ptr @b, i64 0, i64 %index %i4 = bitcast ptr %i3 to ptr %wide.load1 = load <2 x i8>, ptr %i4, align 4 %i5 = zext <2 x i8> %wide.load1 to <2 x i32> %i6 = sub nsw <2 x i32> %i2, %i5 %i7 = icmp sgt <2 x i32> %i6, splat (i32 -1) %i8 = sub nsw <2 x i32> zeroinitializer, %i6 %i9 = select <2 x i1> %i7, <2 x i32> %i6, <2 x i32> %i8 %i10 = add nsw <2 x i32> %i9, %vec.phi %index.next = add i64 %index, 2 %i11 = icmp eq i64 %index.next, 1024 br i1 %i11, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %rdx.shuf = shufflevector <2 x i32> %i10, <2 x i32> undef, <2 x i32> %bin.rdx = add <2 x i32> %i10, %rdx.shuf %i12 = extractelement <2 x i32> %bin.rdx, i32 0 ret i32 %i12 } define dso_local i32 @sad_4i8() #0 { ; CHECK-LABEL: define dso_local i32 @sad_4i8( ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[I10:%.*]], %[[VECTOR_BODY]] ] ; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw i8, ptr @a, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[I]], align 4 ; CHECK-NEXT: [[I2:%.*]] = zext <4 x i8> [[WIDE_LOAD]] to <4 x i32> ; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw i8, ptr @b, i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x i8>, ptr [[I3]], align 4 ; CHECK-NEXT: [[I5:%.*]] = zext <4 x i8> [[WIDE_LOAD1]] to <4 x i32> ; CHECK-NEXT: [[I6:%.*]] = sub nsw <4 x i32> [[I2]], [[I5]] ; CHECK-NEXT: [[I9:%.*]] = tail call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[I6]], i1 true) ; CHECK-NEXT: [[I10]] = add nuw nsw <4 x i32> [[I9]], [[VEC_PHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw nsw i64 [[INDEX]], 4 ; CHECK-NEXT: [[I11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 ; CHECK-NEXT: br i1 [[I11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[I10]]) ; CHECK-NEXT: ret i32 [[SUM]] ; entry: br label %vector.body vector.body: ; preds = %vector.body, %entry %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] %vec.phi = phi <4 x i32> [ zeroinitializer, %entry ], [ %i10, %vector.body ] %i = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index %i1 = bitcast ptr %i to ptr %wide.load = load <4 x i8>, ptr %i1, align 4 %i2 = zext <4 x i8> %wide.load to <4 x i32> %i3 = getelementptr inbounds [1024 x i8], ptr @b, i64 0, i64 %index %i4 = bitcast ptr %i3 to ptr %wide.load1 = load <4 x i8>, ptr %i4, align 4 %i5 = zext <4 x i8> %wide.load1 to <4 x i32> %i6 = sub nsw <4 x i32> %i2, %i5 %i7 = icmp sgt <4 x i32> %i6, splat (i32 -1) %i8 = sub nsw <4 x i32> zeroinitializer, %i6 %i9 = select <4 x i1> %i7, <4 x i32> %i6, <4 x i32> %i8 %i10 = add nsw <4 x i32> %i9, %vec.phi %index.next = add i64 %index, 4 %i11 = icmp eq i64 %index.next, 1024 br i1 %i11, label %middle.block, label %vector.body middle.block: ; preds = %vector.body %h2 = shufflevector <4 x i32> %i10, <4 x i32> undef, <4 x i32> %sum2 = add <4 x i32> %i10, %h2 %h3 = shufflevector <4 x i32> %sum2, <4 x i32> undef, <4 x i32> %sum3 = add <4 x i32> %sum2, %h3 %sum = extractelement <4 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_nonloop_4i8(ptr readonly captures(none) %p, i64 %arg, ptr readonly captures(none) %q) local_unnamed_addr #1 { ; CHECK-LABEL: define dso_local i32 @sad_nonloop_4i8( ; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i64 [[ARG:%.*]], ptr readonly captures(none) [[Q:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V1:%.*]] = load <4 x i8>, ptr [[P]], align 1 ; CHECK-NEXT: [[Z1:%.*]] = zext <4 x i8> [[V1]] to <4 x i32> ; CHECK-NEXT: [[V2:%.*]] = load <4 x i8>, ptr [[Q]], align 1 ; CHECK-NEXT: [[Z2:%.*]] = zext <4 x i8> [[V2]] to <4 x i32> ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <4 x i32> [[Z1]], [[Z2]] ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[SUB]], i1 true) ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[ABS]]) ; CHECK-NEXT: ret i32 [[SUM]] ; bb: %v1 = load <4 x i8>, ptr %p, align 1 %z1 = zext <4 x i8> %v1 to <4 x i32> %v2 = load <4 x i8>, ptr %q, align 1 %z2 = zext <4 x i8> %v2 to <4 x i32> %sub = sub nsw <4 x i32> %z1, %z2 %isneg = icmp sgt <4 x i32> %sub, splat (i32 -1) %neg = sub nsw <4 x i32> zeroinitializer, %sub %abs = select <4 x i1> %isneg, <4 x i32> %sub, <4 x i32> %neg %h2 = shufflevector <4 x i32> %abs, <4 x i32> undef, <4 x i32> %sum2 = add <4 x i32> %abs, %h2 %h3 = shufflevector <4 x i32> %sum2, <4 x i32> undef, <4 x i32> %sum3 = add <4 x i32> %sum2, %h3 %sum = extractelement <4 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_nonloop_8i8(ptr readonly captures(none) %p, i64 %arg, ptr readonly captures(none) %q) local_unnamed_addr #1 { ; CHECK-LABEL: define dso_local i32 @sad_nonloop_8i8( ; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i64 [[ARG:%.*]], ptr readonly captures(none) [[Q:%.*]]) local_unnamed_addr #[[ATTR1]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V1:%.*]] = load <8 x i8>, ptr [[P]], align 1 ; CHECK-NEXT: [[Z1:%.*]] = zext <8 x i8> [[V1]] to <8 x i32> ; CHECK-NEXT: [[V2:%.*]] = load <8 x i8>, ptr [[Q]], align 1 ; CHECK-NEXT: [[Z2:%.*]] = zext <8 x i8> [[V2]] to <8 x i32> ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <8 x i32> [[Z1]], [[Z2]] ; CHECK-NEXT: [[ABS:%.*]] = tail call <8 x i32> @llvm.abs.v8i32(<8 x i32> [[SUB]], i1 true) ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[ABS]]) ; CHECK-NEXT: ret i32 [[SUM]] ; bb: %v1 = load <8 x i8>, ptr %p, align 1 %z1 = zext <8 x i8> %v1 to <8 x i32> %v2 = load <8 x i8>, ptr %q, align 1 %z2 = zext <8 x i8> %v2 to <8 x i32> %sub = sub nsw <8 x i32> %z1, %z2 %isneg = icmp sgt <8 x i32> %sub, splat (i32 -1) %neg = sub nsw <8 x i32> zeroinitializer, %sub %abs = select <8 x i1> %isneg, <8 x i32> %sub, <8 x i32> %neg %h1 = shufflevector <8 x i32> %abs, <8 x i32> undef, <8 x i32> %sum1 = add <8 x i32> %abs, %h1 %h2 = shufflevector <8 x i32> %sum1, <8 x i32> undef, <8 x i32> %sum2 = add <8 x i32> %sum1, %h2 %h3 = shufflevector <8 x i32> %sum2, <8 x i32> undef, <8 x i32> %sum3 = add <8 x i32> %sum2, %h3 %sum = extractelement <8 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_nonloop_16i8(ptr readonly captures(none) %p, i64 %arg, ptr readonly captures(none) %q) local_unnamed_addr #1 { ; CHECK-LABEL: define dso_local i32 @sad_nonloop_16i8( ; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i64 [[ARG:%.*]], ptr readonly captures(none) [[Q:%.*]]) local_unnamed_addr #[[ATTR1]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V1:%.*]] = load <16 x i8>, ptr [[P]], align 1 ; CHECK-NEXT: [[Z1:%.*]] = zext <16 x i8> [[V1]] to <16 x i32> ; CHECK-NEXT: [[V2:%.*]] = load <16 x i8>, ptr [[Q]], align 1 ; CHECK-NEXT: [[Z2:%.*]] = zext <16 x i8> [[V2]] to <16 x i32> ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <16 x i32> [[Z1]], [[Z2]] ; CHECK-NEXT: [[ABS:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[SUB]], i1 true) ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[ABS]]) ; CHECK-NEXT: ret i32 [[SUM]] ; bb: %v1 = load <16 x i8>, ptr %p, align 1 %z1 = zext <16 x i8> %v1 to <16 x i32> %v2 = load <16 x i8>, ptr %q, align 1 %z2 = zext <16 x i8> %v2 to <16 x i32> %sub = sub nsw <16 x i32> %z1, %z2 %isneg = icmp sgt <16 x i32> %sub, splat (i32 -1) %neg = sub nsw <16 x i32> zeroinitializer, %sub %abs = select <16 x i1> %isneg, <16 x i32> %sub, <16 x i32> %neg %h0 = shufflevector <16 x i32> %abs, <16 x i32> undef, <16 x i32> %sum0 = add <16 x i32> %abs, %h0 %h1 = shufflevector <16 x i32> %sum0, <16 x i32> undef, <16 x i32> %sum1 = add <16 x i32> %sum0, %h1 %h2 = shufflevector <16 x i32> %sum1, <16 x i32> undef, <16 x i32> %sum2 = add <16 x i32> %sum1, %h2 %h3 = shufflevector <16 x i32> %sum2, <16 x i32> undef, <16 x i32> %sum3 = add <16 x i32> %sum2, %h3 %sum = extractelement <16 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_nonloop_32i8(ptr readonly captures(none) %p, i64 %arg, ptr readonly captures(none) %q) local_unnamed_addr #1 { ; CHECK-LABEL: define dso_local i32 @sad_nonloop_32i8( ; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i64 [[ARG:%.*]], ptr readonly captures(none) [[Q:%.*]]) local_unnamed_addr #[[ATTR1]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V1:%.*]] = load <32 x i8>, ptr [[P]], align 1 ; CHECK-NEXT: [[Z1:%.*]] = zext <32 x i8> [[V1]] to <32 x i32> ; CHECK-NEXT: [[V2:%.*]] = load <32 x i8>, ptr [[Q]], align 1 ; CHECK-NEXT: [[Z2:%.*]] = zext <32 x i8> [[V2]] to <32 x i32> ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <32 x i32> [[Z1]], [[Z2]] ; CHECK-NEXT: [[ABS:%.*]] = tail call <32 x i32> @llvm.abs.v32i32(<32 x i32> [[SUB]], i1 true) ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> [[ABS]]) ; CHECK-NEXT: ret i32 [[SUM]] ; bb: %v1 = load <32 x i8>, ptr %p, align 1 %z1 = zext <32 x i8> %v1 to <32 x i32> %v2 = load <32 x i8>, ptr %q, align 1 %z2 = zext <32 x i8> %v2 to <32 x i32> %sub = sub nsw <32 x i32> %z1, %z2 %isneg = icmp sgt <32 x i32> %sub, splat (i32 -1) %neg = sub nsw <32 x i32> zeroinitializer, %sub %abs = select <32 x i1> %isneg, <32 x i32> %sub, <32 x i32> %neg %h32 = shufflevector <32 x i32> %abs, <32 x i32> undef, <32 x i32> %sum32 = add <32 x i32> %abs, %h32 %h0 = shufflevector <32 x i32> %sum32, <32 x i32> undef, <32 x i32> %sum0 = add <32 x i32> %sum32, %h0 %h1 = shufflevector <32 x i32> %sum0, <32 x i32> undef, <32 x i32> %sum1 = add <32 x i32> %sum0, %h1 %h2 = shufflevector <32 x i32> %sum1, <32 x i32> undef, <32 x i32> %sum2 = add <32 x i32> %sum1, %h2 %h3 = shufflevector <32 x i32> %sum2, <32 x i32> undef, <32 x i32> %sum3 = add <32 x i32> %sum2, %h3 %sum = extractelement <32 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_nonloop_64i8(ptr readonly captures(none) %p, i64 %arg, ptr readonly captures(none) %q) local_unnamed_addr #1 { ; CHECK-LABEL: define dso_local i32 @sad_nonloop_64i8( ; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i64 [[ARG:%.*]], ptr readonly captures(none) [[Q:%.*]]) local_unnamed_addr #[[ATTR1]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V1:%.*]] = load <64 x i8>, ptr [[P]], align 1 ; CHECK-NEXT: [[Z1:%.*]] = zext <64 x i8> [[V1]] to <64 x i32> ; CHECK-NEXT: [[V2:%.*]] = load <64 x i8>, ptr [[Q]], align 1 ; CHECK-NEXT: [[Z2:%.*]] = zext <64 x i8> [[V2]] to <64 x i32> ; CHECK-NEXT: [[SUB:%.*]] = sub nsw <64 x i32> [[Z1]], [[Z2]] ; CHECK-NEXT: [[ABS:%.*]] = tail call <64 x i32> @llvm.abs.v64i32(<64 x i32> [[SUB]], i1 true) ; CHECK-NEXT: [[SUM:%.*]] = tail call i32 @llvm.vector.reduce.add.v64i32(<64 x i32> [[ABS]]) ; CHECK-NEXT: ret i32 [[SUM]] ; bb: %v1 = load <64 x i8>, ptr %p, align 1 %z1 = zext <64 x i8> %v1 to <64 x i32> %v2 = load <64 x i8>, ptr %q, align 1 %z2 = zext <64 x i8> %v2 to <64 x i32> %sub = sub nsw <64 x i32> %z1, %z2 %isneg = icmp sgt <64 x i32> %sub, splat (i32 -1) %neg = sub nsw <64 x i32> zeroinitializer, %sub %abs = select <64 x i1> %isneg, <64 x i32> %sub, <64 x i32> %neg %h64 = shufflevector <64 x i32> %abs, <64 x i32> undef, <64 x i32> %sum64 = add <64 x i32> %abs, %h64 %h32 = shufflevector <64 x i32> %sum64, <64 x i32> undef, <64 x i32> %sum32 = add <64 x i32> %sum64, %h32 %h0 = shufflevector <64 x i32> %sum32, <64 x i32> undef, <64 x i32> %sum0 = add <64 x i32> %sum32, %h0 %h1 = shufflevector <64 x i32> %sum0, <64 x i32> undef, <64 x i32> %sum1 = add <64 x i32> %sum0, %h1 %h2 = shufflevector <64 x i32> %sum1, <64 x i32> undef, <64 x i32> %sum2 = add <64 x i32> %sum1, %h2 %h3 = shufflevector <64 x i32> %sum2, <64 x i32> undef, <64 x i32> %sum3 = add <64 x i32> %sum2, %h3 %sum = extractelement <64 x i32> %sum3, i32 0 ret i32 %sum } define dso_local i32 @sad_unroll_nonzero_initial(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3) { ; CHECK-LABEL: define dso_local i32 @sad_unroll_nonzero_initial( ; CHECK-SAME: ptr readonly captures(none) [[ARG:%.*]], ptr readonly captures(none) [[ARG1:%.*]], ptr readonly captures(none) [[ARG2:%.*]], ptr readonly captures(none) [[ARG3:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, ptr [[ARG]], align 1 ; CHECK-NEXT: [[TMP4:%.*]] = load <16 x i8>, ptr [[ARG1]], align 1 ; CHECK-NEXT: [[TMP5:%.*]] = zext <16 x i8> [[TMP]] to <16 x i32> ; CHECK-NEXT: [[TMP6:%.*]] = zext <16 x i8> [[TMP4]] to <16 x i32> ; CHECK-NEXT: [[TMP7:%.*]] = sub nsw <16 x i32> [[TMP5]], [[TMP6]] ; CHECK-NEXT: [[TMP10:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP7]], i1 true) ; CHECK-NEXT: [[TMP11:%.*]] = add nuw nsw <16 x i32> [[TMP10]], ; CHECK-NEXT: [[TMP12:%.*]] = load <16 x i8>, ptr [[ARG2]], align 1 ; CHECK-NEXT: [[TMP13:%.*]] = load <16 x i8>, ptr [[ARG3]], align 1 ; CHECK-NEXT: [[TMP14:%.*]] = zext <16 x i8> [[TMP12]] to <16 x i32> ; CHECK-NEXT: [[TMP15:%.*]] = zext <16 x i8> [[TMP13]] to <16 x i32> ; CHECK-NEXT: [[TMP16:%.*]] = sub nsw <16 x i32> [[TMP14]], [[TMP15]] ; CHECK-NEXT: [[TMP19:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP16]], i1 true) ; CHECK-NEXT: [[TMP20:%.*]] = add nuw nsw <16 x i32> [[TMP11]], [[TMP19]] ; CHECK-NEXT: [[TMP29:%.*]] = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP20]]) ; CHECK-NEXT: ret i32 [[TMP29]] ; bb: %i = load <16 x i8>, ptr %arg, align 1 %i4 = load <16 x i8>, ptr %arg1, align 1 %i5 = zext <16 x i8> %i to <16 x i32> %i6 = zext <16 x i8> %i4 to <16 x i32> %i7 = sub nsw <16 x i32> %i5, %i6 %i8 = icmp slt <16 x i32> %i7, zeroinitializer %i9 = sub nsw <16 x i32> zeroinitializer, %i7 %i10 = select <16 x i1> %i8, <16 x i32> %i9, <16 x i32> %i7 %i11 = add nuw nsw <16 x i32> %i10, %i12 = load <16 x i8>, ptr %arg2, align 1 %i13 = load <16 x i8>, ptr %arg3, align 1 %i14 = zext <16 x i8> %i12 to <16 x i32> %i15 = zext <16 x i8> %i13 to <16 x i32> %i16 = sub nsw <16 x i32> %i14, %i15 %i17 = icmp slt <16 x i32> %i16, zeroinitializer %i18 = sub nsw <16 x i32> zeroinitializer, %i16 %i19 = select <16 x i1> %i17, <16 x i32> %i18, <16 x i32> %i16 %i20 = add nuw nsw <16 x i32> %i19, %i11 %i21 = shufflevector <16 x i32> %i20, <16 x i32> undef, <16 x i32> %i22 = add <16 x i32> %i20, %i21 %i23 = shufflevector <16 x i32> %i22, <16 x i32> undef, <16 x i32> %i24 = add <16 x i32> %i22, %i23 %i25 = shufflevector <16 x i32> %i24, <16 x i32> undef, <16 x i32> %i26 = add <16 x i32> %i24, %i25 %i27 = shufflevector <16 x i32> %i26, <16 x i32> undef, <16 x i32> %i28 = add <16 x i32> %i26, %i27 %i29 = extractelement <16 x i32> %i28, i64 0 ret i32 %i29 } define dso_local i32 @sad_double_reduction(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3) { ; CHECK-LABEL: define dso_local i32 @sad_double_reduction( ; CHECK-SAME: ptr readonly captures(none) [[ARG:%.*]], ptr readonly captures(none) [[ARG1:%.*]], ptr readonly captures(none) [[ARG2:%.*]], ptr readonly captures(none) [[ARG3:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, ptr [[ARG]], align 1 ; CHECK-NEXT: [[TMP4:%.*]] = load <16 x i8>, ptr [[ARG1]], align 1 ; CHECK-NEXT: [[TMP5:%.*]] = zext <16 x i8> [[TMP]] to <16 x i32> ; CHECK-NEXT: [[TMP6:%.*]] = zext <16 x i8> [[TMP4]] to <16 x i32> ; CHECK-NEXT: [[TMP7:%.*]] = sub nsw <16 x i32> [[TMP5]], [[TMP6]] ; CHECK-NEXT: [[TMP10:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP7]], i1 true) ; CHECK-NEXT: [[TMP11:%.*]] = load <16 x i8>, ptr [[ARG2]], align 1 ; CHECK-NEXT: [[TMP12:%.*]] = load <16 x i8>, ptr [[ARG3]], align 1 ; CHECK-NEXT: [[TMP13:%.*]] = zext <16 x i8> [[TMP11]] to <16 x i32> ; CHECK-NEXT: [[TMP14:%.*]] = zext <16 x i8> [[TMP12]] to <16 x i32> ; CHECK-NEXT: [[TMP15:%.*]] = sub nsw <16 x i32> [[TMP13]], [[TMP14]] ; CHECK-NEXT: [[TMP18:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP15]], i1 true) ; CHECK-NEXT: [[TMP19:%.*]] = add nuw nsw <16 x i32> [[TMP18]], [[TMP10]] ; CHECK-NEXT: [[TMP28:%.*]] = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP19]]) ; CHECK-NEXT: ret i32 [[TMP28]] ; bb: %i = load <16 x i8>, ptr %arg, align 1 %i4 = load <16 x i8>, ptr %arg1, align 1 %i5 = zext <16 x i8> %i to <16 x i32> %i6 = zext <16 x i8> %i4 to <16 x i32> %i7 = sub nsw <16 x i32> %i5, %i6 %i8 = icmp slt <16 x i32> %i7, zeroinitializer %i9 = sub nsw <16 x i32> zeroinitializer, %i7 %i10 = select <16 x i1> %i8, <16 x i32> %i9, <16 x i32> %i7 %i11 = load <16 x i8>, ptr %arg2, align 1 %i12 = load <16 x i8>, ptr %arg3, align 1 %i13 = zext <16 x i8> %i11 to <16 x i32> %i14 = zext <16 x i8> %i12 to <16 x i32> %i15 = sub nsw <16 x i32> %i13, %i14 %i16 = icmp slt <16 x i32> %i15, zeroinitializer %i17 = sub nsw <16 x i32> zeroinitializer, %i15 %i18 = select <16 x i1> %i16, <16 x i32> %i17, <16 x i32> %i15 %i19 = add nuw nsw <16 x i32> %i18, %i10 %i20 = shufflevector <16 x i32> %i19, <16 x i32> undef, <16 x i32> %i21 = add <16 x i32> %i19, %i20 %i22 = shufflevector <16 x i32> %i21, <16 x i32> undef, <16 x i32> %i23 = add <16 x i32> %i21, %i22 %i24 = shufflevector <16 x i32> %i23, <16 x i32> undef, <16 x i32> %i25 = add <16 x i32> %i23, %i24 %i26 = shufflevector <16 x i32> %i25, <16 x i32> undef, <16 x i32> %i27 = add <16 x i32> %i25, %i26 %i28 = extractelement <16 x i32> %i27, i64 0 ret i32 %i28 } define dso_local i32 @sad_double_reduction_abs(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3) { ; CHECK-LABEL: define dso_local i32 @sad_double_reduction_abs( ; CHECK-SAME: ptr readonly captures(none) [[ARG:%.*]], ptr readonly captures(none) [[ARG1:%.*]], ptr readonly captures(none) [[ARG2:%.*]], ptr readonly captures(none) [[ARG3:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, ptr [[ARG]], align 1 ; CHECK-NEXT: [[TMP4:%.*]] = load <16 x i8>, ptr [[ARG1]], align 1 ; CHECK-NEXT: [[TMP5:%.*]] = zext <16 x i8> [[TMP]] to <16 x i32> ; CHECK-NEXT: [[TMP6:%.*]] = zext <16 x i8> [[TMP4]] to <16 x i32> ; CHECK-NEXT: [[TMP7:%.*]] = sub nsw <16 x i32> [[TMP5]], [[TMP6]] ; CHECK-NEXT: [[TMP10:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP7]], i1 true) ; CHECK-NEXT: [[TMP11:%.*]] = load <16 x i8>, ptr [[ARG2]], align 1 ; CHECK-NEXT: [[TMP12:%.*]] = load <16 x i8>, ptr [[ARG3]], align 1 ; CHECK-NEXT: [[TMP13:%.*]] = zext <16 x i8> [[TMP11]] to <16 x i32> ; CHECK-NEXT: [[TMP14:%.*]] = zext <16 x i8> [[TMP12]] to <16 x i32> ; CHECK-NEXT: [[TMP15:%.*]] = sub nsw <16 x i32> [[TMP13]], [[TMP14]] ; CHECK-NEXT: [[TMP18:%.*]] = tail call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[TMP15]], i1 true) ; CHECK-NEXT: [[TMP19:%.*]] = add nuw nsw <16 x i32> [[TMP18]], [[TMP10]] ; CHECK-NEXT: [[TMP28:%.*]] = tail call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP19]]) ; CHECK-NEXT: ret i32 [[TMP28]] ; bb: %i = load <16 x i8>, ptr %arg, align 1 %i4 = load <16 x i8>, ptr %arg1, align 1 %i5 = zext <16 x i8> %i to <16 x i32> %i6 = zext <16 x i8> %i4 to <16 x i32> %i7 = sub nsw <16 x i32> %i5, %i6 %i10 = call <16 x i32> @llvm.abs.v16i32(<16 x i32> %i7, i1 false) %i11 = load <16 x i8>, ptr %arg2, align 1 %i12 = load <16 x i8>, ptr %arg3, align 1 %i13 = zext <16 x i8> %i11 to <16 x i32> %i14 = zext <16 x i8> %i12 to <16 x i32> %i15 = sub nsw <16 x i32> %i13, %i14 %i18 = call <16 x i32> @llvm.abs.v16i32(<16 x i32> %i15, i1 false) %i19 = add nuw nsw <16 x i32> %i18, %i10 %i20 = shufflevector <16 x i32> %i19, <16 x i32> undef, <16 x i32> %i21 = add <16 x i32> %i19, %i20 %i22 = shufflevector <16 x i32> %i21, <16 x i32> undef, <16 x i32> %i23 = add <16 x i32> %i21, %i22 %i24 = shufflevector <16 x i32> %i23, <16 x i32> undef, <16 x i32> %i25 = add <16 x i32> %i23, %i24 %i26 = shufflevector <16 x i32> %i25, <16 x i32> undef, <16 x i32> %i27 = add <16 x i32> %i25, %i26 %i28 = extractelement <16 x i32> %i27, i64 0 ret i32 %i28 } define i32 @PR143456(ptr %p0, ptr %p1) { ; CHECK-LABEL: define range(i32 0, 256) i32 @PR143456( ; CHECK-SAME: ptr readonly captures(none) [[P0:%.*]], ptr readonly captures(none) [[P1:%.*]]) local_unnamed_addr #[[ATTR2]] { ; CHECK-NEXT: [[BB:.*:]] ; CHECK-NEXT: [[V0:%.*]] = load <8 x i8>, ptr [[P0]], align 1 ; CHECK-NEXT: [[V1:%.*]] = load <8 x i8>, ptr [[P1]], align 1 ; CHECK-NEXT: [[MAX:%.*]] = tail call <8 x i8> @llvm.umax.v8i8(<8 x i8> [[V0]], <8 x i8> [[V1]]) ; CHECK-NEXT: [[MIN:%.*]] = tail call <8 x i8> @llvm.umin.v8i8(<8 x i8> [[V0]], <8 x i8> [[V1]]) ; CHECK-NEXT: [[ABD:%.*]] = sub nuw <8 x i8> [[MAX]], [[MIN]] ; CHECK-NEXT: [[ELT:%.*]] = tail call i8 @llvm.vector.reduce.add.v8i8(<8 x i8> [[ABD]]) ; CHECK-NEXT: [[RES:%.*]] = zext i8 [[ELT]] to i32 ; CHECK-NEXT: ret i32 [[RES]] ; bb: %v0 = load <8 x i8>, ptr %p0, align 1 %v1 = load <8 x i8>, ptr %p1, align 1 %max = tail call <8 x i8> @llvm.umax.v8i8(<8 x i8> %v0, <8 x i8> %v1) %min = tail call <8 x i8> @llvm.umin.v8i8(<8 x i8> %v0, <8 x i8> %v1) %abd = sub nuw <8 x i8> %max, %min %rdx.shuf = shufflevector <8 x i8> %abd, <8 x i8> poison, <8 x i32> %bin.rdx = add <8 x i8> %abd, %rdx.shuf %rdx.shuf15 = shufflevector <8 x i8> %bin.rdx, <8 x i8> poison, <8 x i32> %bin.rdx16 = add <8 x i8> %bin.rdx, %rdx.shuf15 %rdx.shuf17 = shufflevector <8 x i8> %bin.rdx16, <8 x i8> poison, <8 x i32> %bin.rdx18 = add <8 x i8> %bin.rdx16, %rdx.shuf17 %elt = extractelement <8 x i8> %bin.rdx18, i32 0 %res = zext i8 %elt to i32 ret i32 %res } attributes #0 = { nounwind } attributes #1 = { nofree nosync nounwind speculatable willreturn memory(none) } attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }