https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81763
--- Comment #27 from Manuel Lauss <manuel.lauss at googlemail dot com> --- (In reply to Uroš Bizjak from comment #21) > Following patch should fix the problem: > > --cut here-- > Index: i386.md > =================================================================== > --- i386.md (revision 256935) > +++ i386.md (working copy) > @@ -9250,10 +9250,10 @@ > }) > > (define_insn "*andndi3_doubleword" > - [(set (match_operand:DI 0 "register_operand" "=r,&r") > + [(set (match_operand:DI 0 "register_operand" "=r,r") > (and:DI > (not:DI (match_operand:DI 1 "register_operand" "r,0")) > - (match_operand:DI 2 "nonimmediate_operand" "rm,rm"))) > + (match_operand:DI 2 "nonimmediate_operand" "r,rm"))) > (clobber (reg:CC FLAGS_REG))] > "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" > "#" > --cut here-- > > So, the pattern now reads: > > (define_insn "*andndi3_doubleword" > [(set (match_operand:DI 0 "register_operand" "=r,r") > (and:DI > (not:DI (match_operand:DI 1 "register_operand" "r,0")) > (match_operand:DI 2 "nonimmediate_operand" "r,rm"))) > (clobber (reg:CC FLAGS_REG))] > "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" > "#" > [(set_attr "isa" "bmi,*")]) I rebuilt gcc-7.3 with this applied, now the generated code looks much better: ab: 0f ad d0 shrd %cl,%edx,%eax ae: f6 c1 20 test $0x20,%cl b1: c4 e2 73 f7 d2 shrx %ecx,%edx,%edx b6: 0f 45 c2 cmovne %edx,%eax b9: 0f 45 d5 cmovne %ebp,%edx bc: c4 e2 68 f2 54 df 04 andn 0x4(%edi,%ebx,8),%edx,%edx c3: 89 d1 mov %edx,%ecx c5: c4 e2 78 f2 04 df andn (%edi,%ebx,8),%eax,%eax cb: 09 c1 or %eax,%ecx And it seems to work as well, 32bit llvm now built successfully.