Index: lib/Target/X86/X86InstrInfo.td =================================================================== --- lib/Target/X86/X86InstrInfo.td +++ lib/Target/X86/X86InstrInfo.td @@ -2429,6 +2429,7 @@ } let Predicates = [HasBMI2] in { + // x & ((1 << y) + (-1)) def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)), (BZHI32rr GR32:$src, (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>; @@ -2445,6 +2446,12 @@ (BZHI64rm addr:$src, (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>; + // x & ~(-1 << y) + def : Pat<(and GR32:$src, (xor(shl -1, (i8 (trunc GR32:$lz))), -1)), + (BZHI32rr GR32:$src, GR32:$lz)>; + def : Pat<(and (loadi32 addr:$src), (xor(shl -1, (i8 (trunc GR32:$lz))), -1)), + (BZHI32rm addr:$src, GR32:$lz)>; + // x & (-1 >> (32 - y)) def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))), (BZHI32rr GR32:$src, GR32:$lz)>; Index: test/CodeGen/X86/get-lowbits.ll =================================================================== --- test/CodeGen/X86/get-lowbits.ll +++ test/CodeGen/X86/get-lowbits.ll @@ -34,9 +34,7 @@ ; ; CHECK-BMI2-LABEL: test0: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i16 %nbits to i32 @@ -103,9 +101,7 @@ ; ; CHECK-BMI2-LABEL: test2: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = shl i32 -1, %nbits @@ -170,9 +166,7 @@ ; ; CHECK-BMI2-LABEL: test4: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 @@ -239,9 +233,7 @@ ; ; CHECK-BMI2-LABEL: test6: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -310,9 +302,7 @@ ; ; CHECK-BMI2-LABEL: test8: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -449,9 +439,7 @@ ; ; CHECK-BMI2-LABEL: test12: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -520,9 +508,7 @@ ; ; CHECK-BMI2-LABEL: test14: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 @@ -591,9 +577,7 @@ ; ; CHECK-BMI2-LABEL: test16: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i16 %nbits to i32 @@ -660,9 +644,7 @@ ; ; CHECK-BMI2-LABEL: test18: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = shl i32 -1, %nbits @@ -727,9 +709,7 @@ ; ; CHECK-BMI2-LABEL: test20: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 @@ -796,9 +776,7 @@ ; ; CHECK-BMI2-LABEL: test22: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -867,9 +845,7 @@ ; ; CHECK-BMI2-LABEL: test24: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -1006,9 +982,7 @@ ; ; CHECK-BMI2-LABEL: test28: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 @@ -1077,9 +1051,7 @@ ; ; CHECK-BMI2-LABEL: test30: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 @@ -1146,9 +1118,7 @@ ; ; CHECK-BMI2-LABEL: test32: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: retq %tmp = shl i32 -1, %nbits %tmp2 = xor i32 %tmp, -1 @@ -1205,9 +1175,7 @@ ; ; CHECK-BMI2-LABEL: test34: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 %tmp2 = shl i32 -1, %tmp @@ -1266,9 +1234,7 @@ ; ; CHECK-BMI2-LABEL: test36: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 %tmp2 = shl i32 -1, %nbits @@ -1395,9 +1361,7 @@ ; ; CHECK-BMI2-LABEL: test40: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: retq %tmp = trunc i64 %val to i32 %tmp2 = zext i8 %nbits to i32 @@ -1458,9 +1422,7 @@ ; ; CHECK-BMI2-LABEL: test42: ; CHECK-BMI2: # %bb.0: -; CHECK-BMI2-NEXT: movl $-1, %eax -; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax -; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax ; CHECK-BMI2-NEXT: retq %tmp = zext i8 %nbits to i32 %tmp2 = shl i32 -1, %tmp