; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -p instcombine -S %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define i1 @vreduce_and_eq(<4 x i8> %v) { ; CHECK-LABEL: define i1 @vreduce_and_eq( ; CHECK-SAME: <4 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[V]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %v) %cmp = icmp eq i8 %red, -1 ret i1 %cmp } define i1 @vreduce_and_ne(<4 x i8> %v) { ; CHECK-LABEL: define i1 @vreduce_and_ne( ; CHECK-SAME: <4 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[V]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %v) %cmp = icmp ne i8 %red, -1 ret i1 %cmp } define i1 @vreduce_or_eq(<4 x i8> %v) { ; CHECK-LABEL: define i1 @vreduce_or_eq( ; CHECK-SAME: <4 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[V]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> %v) %cmp = icmp eq i8 %red, 0 ret i1 %cmp } define i1 @vreduce_or_ne(<4 x i8> %v) { ; CHECK-LABEL: define i1 @vreduce_or_ne( ; CHECK-SAME: <4 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[V]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> %v) %cmp = icmp ne i8 %red, 0 ret i1 %cmp } define i1 @loaded_value(ptr %p) { ; CHECK-LABEL: define i1 @loaded_value( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V1]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %v = load <4 x i8>, ptr %p %red = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %v) %cmp = icmp eq i8 %red, -1 ret i1 %cmp } define i1 @vector_elt_type_legality(<4 x i32> %v) { ; CHECK-LABEL: define i1 @vector_elt_type_legality( ; CHECK-SAME: <4 x i32> [[V:%.*]]) { ; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[V]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[RED]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %v) %cmp = icmp ne i32 %red, 0 ret i1 %cmp } define i1 @vreduce_and_sgt(<4 x i8> %v) { ; CHECK-LABEL: define i1 @vreduce_and_sgt( ; CHECK-SAME: <4 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RED:%.*]] = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> [[V]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[RED]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %v) %cmp = icmp sgt i8 %red, -1 ret i1 %cmp } define i1 @scalable( %v) { ; CHECK-LABEL: define i1 @scalable( ; CHECK-SAME: [[V:%.*]]) { ; CHECK-NEXT: [[RED:%.*]] = call i8 @llvm.vector.reduce.and.nxv4i8( [[V]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[RED]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i8 @llvm.vector.reduce.and.nxv4i8( %v) %cmp = icmp eq i8 %red, -1 ret i1 %cmp } declare void @use(i16) define i1 @multiuse.or(<4 x i16> %v) { ; CHECK-LABEL: define i1 @multiuse.or( ; CHECK-SAME: <4 x i16> [[V:%.*]]) { ; CHECK-NEXT: [[RED:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[V]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[RED]], 0 ; CHECK-NEXT: call void @use(i16 [[RED]]) ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> %v) %cmp = icmp ne i16 %red, 0 call void @use(i16 %red) ret i1 %cmp } define i1 @multiuse.and(<4 x i16> %v) { ; CHECK-LABEL: define i1 @multiuse.and( ; CHECK-SAME: <4 x i16> [[V:%.*]]) { ; CHECK-NEXT: [[RED:%.*]] = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> [[V]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[RED]], 0 ; CHECK-NEXT: call void @use(i16 [[RED]]) ; CHECK-NEXT: ret i1 [[CMP]] ; %red = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> %v) %cmp = icmp ne i16 %red, 0 call void @use(i16 %red) ret i1 %cmp }