| ; 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 |
| } |