blob: 0c376c122b8541bdea6081ce59ad0f54230bb0ee [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=vector-combine -mtriple=riscv64 -mattr=+v < %s | FileCheck %s
define i1 @nn_zext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @nn_zext_eq_0(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
%zb = zext <4 x i1> %b to <4 x i32>
%add = add nuw <4 x i32> %za, %zb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp eq i32 %red, 0
ret i1 %cmp
}
define i1 @np_sext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @np_sext_eq_0(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
%sb = sext <4 x i1> %b to <4 x i32>
%add = add nsw <4 x i32> %sa, %sb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp eq i32 %red, 0
ret i1 %cmp
}
define i1 @np_sext_ne_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @np_sext_ne_0(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
%sb = sext <4 x i1> %b to <4 x i32>
%add = add nsw <4 x i32> %sa, %sb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp ne i32 %red, 0
ret i1 %cmp
}
; Tautological: NN tree + sge 0 is always true; the fold must not rewrite
; the predicate into a non-tautological form.
define i1 @nn_sge_0_tautological(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @nn_sge_0_tautological(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[ADD]])
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[RED]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
%zb = zext <4 x i1> %b to <4 x i32>
%add = add nuw <4 x i32> %za, %zb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp sge i32 %red, 0
ret i1 %cmp
}
define i1 @np_sle_0_tautological(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @np_sle_0_tautological(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[ADD]])
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[RED]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
%sb = sext <4 x i1> %b to <4 x i32>
%add = add nsw <4 x i32> %sa, %sb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp sle i32 %red, 0
ret i1 %cmp
}
define i1 @mixed_sign_bail(<4 x i1> %a, <4 x i1> %b) {
; CHECK-LABEL: define i1 @mixed_sign_bail(
; CHECK-SAME: <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[SA]], [[ZB]]
; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[ADD]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
%zb = zext <4 x i1> %b to <4 x i32>
%add = add <4 x i32> %sa, %zb
%red = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %add)
%cmp = icmp eq i32 %red, 0
ret i1 %cmp
}