; RUN: opt -S -passes=instcombine < %s | FileCheck %s ; This was separated from simplify-demanded-fpclass.ll to work around ; alive2 bug. ; Basic aggregate tests to ensure this does not crash. define nofpclass(nan) { float } @ret_nofpclass_struct_ty() { ; CHECK-LABEL: define nofpclass(nan) { float } @ret_nofpclass_struct_ty() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float } zeroinitializer ; entry: ret { float } zeroinitializer } define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() { ; CHECK-LABEL: define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float, float } zeroinitializer ; entry: ret { float, float } zeroinitializer } define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() { ; CHECK-LABEL: define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { <4 x float>, <4 x float> } zeroinitializer ; entry: ret { <4 x float>, <4 x float> } zeroinitializer } define nofpclass(nan) [ 5 x float ] @ret_nofpclass_array_ty() { ; CHECK-LABEL: define nofpclass(nan) [5 x float] @ret_nofpclass_array_ty() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret [5 x float] zeroinitializer ; entry: ret [ 5 x float ] zeroinitializer } define nofpclass(nan) [ 2 x [ 5 x float ]] @ret_nofpclass_nested_array_ty() { ; CHECK-LABEL: define nofpclass(nan) [2 x [5 x float]] @ret_nofpclass_nested_array_ty() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret [2 x [5 x float]] zeroinitializer ; entry: ret [ 2 x [ 5 x float ]] zeroinitializer } define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() { ; CHECK-LABEL: define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float } { float -inf } ; entry: ret { float } { float 0xFFF0000000000000 } } define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() { ; CHECK-LABEL: define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float, float } { float -inf, float -inf } ; entry: ret { float, float } { float 0xFFF0000000000000, float 0xFFF0000000000000 } } define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() { ; CHECK-LABEL: define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { <2 x float> } { <2 x float> splat (float -inf) } ; entry: ret { <2 x float>} { <2 x float> } } ; UTC_ARGS: --disable ; FileCheck does not like the nested square brackets. define nofpclass(pinf) [ 1 x [ 1 x float ]] @ret_nofpclass_nested_array_ty_pinf__ninf() { ; CHECK-LABEL: @ret_nofpclass_nested_array_ty_pinf__ninf() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret {{.*}}float -inf ; entry: ret [ 1 x [ 1 x float ]] [[ 1 x float ] [float 0xFFF0000000000000]] } ; UTC_ARGS: --enable define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() { ; CHECK-LABEL: define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float, float } { float -0.000000e+00, float -0.000000e+00 } ; entry: ret { float, float } { float -0.0, float -0.0 } } define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() { ; CHECK-LABEL: define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret { float, float } { float +inf, float +inf } ; entry: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 } } define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() { ; CHECK-LABEL: define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret { float, float } poison ; entry: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 } } define nofpclass(nzero) [ 1 x float ] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() { ; CHECK-LABEL: define nofpclass(nzero) [1 x float] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret [1 x float] poison ; entry: ret [ 1 x float ] [ float -0.0 ] } ; Fold to ret %y define nofpclass(inf) [3 x [2 x float]] @ret_float_array(i1 %cond, [3 x [2 x float]] nofpclass(nan norm zero sub) %x, [3 x [2 x float]] %y) { ; CHECK-LABEL: define nofpclass(inf) [3 x [2 x float]] @ret_float_array( ; CHECK-SAME: i1 [[COND:%.*]], [3 x [2 x float]] nofpclass(nan zero sub norm) [[X:%.*]], [3 x [2 x float]] [[Y:%.*]]) { ; CHECK-NEXT: ret [3 x [2 x float]] [[Y]] ; %select = select i1 %cond, [3 x [2 x float]] %x, [3 x [2 x float]] %y ret [3 x [2 x float ]] %select } define nofpclass(nan) float @simplify_demanded_extractvalue_array(i1 %cond, [2 x float] %arg0) { ; CHECK-LABEL: define nofpclass(nan) float @simplify_demanded_extractvalue_array( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARG0:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue [2 x float] [[ARG0]], 0 ; CHECK-NEXT: ret float [[TMP1]] ; %select = select i1 %cond, [2 x float] %arg0, [2 x float] [float 0x7FF8000000000000, float 0x7FF8000000000000] %extract = extractvalue [2 x float] %select, 0 ret float %extract } define nofpclass(nan) float @simplify_demanded_extractvalue_array_partial_positive(i1 %cond, [2 x float] %arg0) { ; CHECK-LABEL: define nofpclass(nan) float @simplify_demanded_extractvalue_array_partial_positive( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARG0:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue [2 x float] [[ARG0]], 1 ; CHECK-NEXT: [[EXTRACT:%.*]] = select i1 [[COND]], float [[TMP1]], float 0.000000e+00 ; CHECK-NEXT: ret float [[EXTRACT]] ; %select = select i1 %cond, [2 x float] %arg0, [2 x float] [float 0x7FF8000000000000, float 0.0] %extract = extractvalue [2 x float] %select, 1 ret float %extract } define nofpclass(nan) float @simplify_demanded_extractvalue_array_partialnegative(i1 %cond, [2 x float] %arg0) { ; CHECK-LABEL: define nofpclass(nan) float @simplify_demanded_extractvalue_array_partialnegative( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARG0:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue [2 x float] [[ARG0]], 1 ; CHECK-NEXT: ret float [[TMP1]] ; %select = select i1 %cond, [2 x float] %arg0, [2 x float] [float 0.0, float 0x7FF8000000000000] %extract = extractvalue [2 x float] %select, 1 ret float %extract } define nofpclass(nan) float @simplify_demanded_extractvalue_struct(i1 %cond, { float, float } %arg0) { ; CHECK-LABEL: define nofpclass(nan) float @simplify_demanded_extractvalue_struct( ; CHECK-SAME: i1 [[COND:%.*]], { float, float } [[ARG0:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { float, float } [[ARG0]], 0 ; CHECK-NEXT: ret float [[TMP1]] ; %select = select i1 %cond, { float, float } %arg0, { float, float } {float 0x7FF8000000000000, float 0x7FF8000000000000} %extract = extractvalue { float, float } %select, 0 ret float %extract } define nofpclass(inf norm sub zero) float @simplify_demanded_extractvalue_only_nan(i1 %cond, [2 x float] %arg0) { ; CHECK-LABEL: define nofpclass(inf zero sub norm) float @simplify_demanded_extractvalue_only_nan( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARG0:%.*]]) { ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue [2 x float] [[ARG0]], 0 ; CHECK-NEXT: [[EXTRACT:%.*]] = select i1 [[COND]], float [[TMP1]], float +qnan ; CHECK-NEXT: ret float [[EXTRACT]] ; %select = select i1 %cond, [2 x float] %arg0, [2 x float] [float 0x7FF8000000000000, float 0x7FF8000000000000] %extract = extractvalue [2 x float] %select, 0 ret float %extract } define nofpclass(nan inf norm sub nzero) float @simplify_demanded_extractvalue_only_pzero(i1 %cond, [2 x float] %arg0) { ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @simplify_demanded_extractvalue_only_pzero( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARG0:%.*]]) { ; CHECK-NEXT: ret float 0.000000e+00 ; %select = select i1 %cond, [2 x float] %arg0, [2 x float] [float 0x7FF8000000000000, float 0x7FF8000000000000] %extract = extractvalue [2 x float] %select, 0 ret float %extract } define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_insertee(i1 %cond, [2 x float] %array, float %unknown) { ; CHECK-LABEL: define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_insertee( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue [2 x float] [[ARRAY]], float [[UNKNOWN]], 0 ; CHECK-NEXT: ret [2 x float] [[INSERT]] ; %select = select i1 %cond, float 0x7FF8000000000000, float %unknown %insert = insertvalue [2 x float] %array, float %select, 0 ret [2 x float] %insert } define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_inserted(i1 %cond, [2 x float] %array, float %unknown) { ; CHECK-LABEL: define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_inserted( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue [2 x float] [[ARRAY]], float [[UNKNOWN]], 0 ; CHECK-NEXT: ret [2 x float] [[INSERT]] ; %select = select i1 %cond, [2 x float] %array, [2 x float] [float 0x7FF8000000000000, float 0x7FF8000000000000] %insert = insertvalue [2 x float] %select, float %unknown, 0 ret [2 x float] %insert } define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_both(i1 %cond, [2 x float] %array, float %unknown) { ; CHECK-LABEL: define nofpclass(nan) [2 x float] @simplify_demanded_insertvalue_array_both( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue [2 x float] [[ARRAY]], float [[UNKNOWN]], 0 ; CHECK-NEXT: ret [2 x float] [[INSERT]] ; %select.array = select i1 %cond, [2 x float] %array, [2 x float] [float 0x7FF8000000000000, float 0x7FF8000000000000] %select.scalar = select i1 %cond, float 0x7FF8000000000000, float %unknown %insert = insertvalue [2 x float] %select.array, float %select.scalar, 0 ret [2 x float] %insert } define nofpclass(inf norm sub zero) [2 x float] @only_nan_simplify_demanded_insertvalue_array(i1 %cond, [2 x float] %array, float %unknown) { ; CHECK-LABEL: define nofpclass(inf zero sub norm) [2 x float] @only_nan_simplify_demanded_insertvalue_array( ; CHECK-SAME: i1 [[COND:%.*]], [2 x float] [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float +qnan, float [[UNKNOWN]] ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue [2 x float] [[ARRAY]], float [[SELECT]], 0 ; CHECK-NEXT: ret [2 x float] [[INSERT]] ; %select = select i1 %cond, float 0x7FF8000000000000, float %unknown %insert = insertvalue [2 x float] %array, float %select, 0 ret [2 x float] %insert } define nofpclass(nan) { float, float } @simplify_demanded_insertvalue_struct_inserted(i1 %cond, { float, float } %array, float %unknown) { ; CHECK-LABEL: define nofpclass(nan) { float, float } @simplify_demanded_insertvalue_struct_inserted( ; CHECK-SAME: i1 [[COND:%.*]], { float, float } [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue { float, float } [[ARRAY]], float [[UNKNOWN]], 0 ; CHECK-NEXT: ret { float, float } [[INSERT]] ; %select = select i1 %cond, { float, float } %array, { float, float } { float 0x7FF8000000000000, float 0x7FF8000000000000 } %insert = insertvalue { float, float } %select, float %unknown, 0 ret { float, float } %insert } define nofpclass(nan) { float, float } @simplify_demanded_insertvalue_struct_insertee(i1 %cond, { float, float } %array, float %unknown) { ; CHECK-LABEL: define nofpclass(nan) { float, float } @simplify_demanded_insertvalue_struct_insertee( ; CHECK-SAME: i1 [[COND:%.*]], { float, float } [[ARRAY:%.*]], float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[INSERT:%.*]] = insertvalue { float, float } [[ARRAY]], float [[UNKNOWN]], 0 ; CHECK-NEXT: ret { float, float } [[INSERT]] ; %select = select i1 %cond, float 0x7FF8000000000000, float %unknown %insert = insertvalue { float, float } %array, float %select, 0 ret { float, float } %insert }