https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93637
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- It is a blend, so yes, it can be represented as VEC_PERM_EXPR, or using vcond_mask_optab etc. The trouble is that TARGET_AVX && !TARGET_AVX2 is really weird when 32-byte integral modes are involved and the question is what the middle-end should try as a fallback if it sees the vcond{,u} failing when the condition is constant. Because VEC_PERM_EXPR is said not to be supported: typedef long long __v4di __attribute__((vector_size (32))); __v4di foo (__v4di z, __v4di u) { return __builtin_shuffle (z, u, (__v4di) { 0, 1, 6, 3 }); } with -mavx this is lowered during veclower. I'd say we either should enable vcond_mask* even for V4DI/V8SI, or disable vcond{v4div4df,v8siv8sf} for !TARGET_AVX2 && TARGET_AVX. Untested patch to do the former fixes the ICE: --- gcc/config/i386/sse.md.jj 2020-02-10 13:14:02.970131692 +0100 +++ gcc/config/i386/sse.md 2020-02-10 13:14:43.689525366 +0100 @@ -3430,13 +3430,19 @@ (define_expand "vcond_mask_<mode><avx512 (match_operand:<avx512fmaskmode> 3 "register_operand")))] "TARGET_AVX512BW") +;; As vcondv4div4df and vcondv8siv8sf are enabled already with TARGET_AVX, +;; and their condition can be folded late into a constant, we need to +;; support vcond_mask_v4div4di and vcond_mask_v8siv8si for TARGET_AVX. +(define_mode_iterator VI_256_AVX2 [(V32QI "TARGET_AVX2") (V16HI "TARGET_AVX2") + V8SI V4DI]) + (define_expand "vcond_mask_<mode><sseintvecmodelower>" - [(set (match_operand:VI_256 0 "register_operand") - (vec_merge:VI_256 - (match_operand:VI_256 1 "nonimmediate_operand") - (match_operand:VI_256 2 "nonimm_or_0_operand") + [(set (match_operand:VI_256_AVX2 0 "register_operand") + (vec_merge:VI_256_AVX2 + (match_operand:VI_256_AVX2 1 "nonimmediate_operand") + (match_operand:VI_256_AVX2 2 "nonimm_or_0_operand") (match_operand:<sseintvecmode> 3 "register_operand")))] - "TARGET_AVX2" + "TARGET_AVX" { ix86_expand_sse_movcc (operands[0], operands[3], operands[1], operands[2]);