Index: test/CodeGen/AArch64/get-lowbits.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/get-lowbits.ll @@ -0,0 +1,800 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s + +; https://bugs.llvm.org/show_bug.cgi?id=36419 +; https://bugs.llvm.org/show_bug.cgi?id=37603 +; https://bugs.llvm.org/show_bug.cgi?id=37610 + +; Patterns: +; (1 << nbits) - 1 +; ~(-(1 << nbits)) +; Are equivalent. + +define i8 @test0(i32 %val, i16 %nbits) { +; CHECK-LABEL: test0: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test1(i32 %val, i16 %nbits) { +; CHECK-LABEL: test1: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test2(i32 %val, i32 %nbits) { +; CHECK-LABEL: test2: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, 255 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test3(i32 %val, i32 %nbits) { +; CHECK-LABEL: test3: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i32 1, %nbits + %tmp2 = add i32 %tmp, 255 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test4(i32 %val, i8 %nbits) { +; CHECK-LABEL: test4: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test5(i32 %val, i8 %nbits) { +; CHECK-LABEL: test5: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test6(i64 %val, i16 %nbits) { +; CHECK-LABEL: test6: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test7(i64 %val, i16 %nbits) { +; CHECK-LABEL: test7: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test8(i64 %val, i32 %nbits) { +; CHECK-LABEL: test8: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test9(i64 %val, i32 %nbits) { +; CHECK-LABEL: test9: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test10(i64 %val, i64 %nbits) { +; CHECK-LABEL: test10: +; CHECK: // %bb.0: +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 255 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test11(i64 %val, i64 %nbits) { +; CHECK-LABEL: test11: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 255 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test12(i64 %val, i8 %nbits) { +; CHECK-LABEL: test12: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test13(i64 %val, i8 %nbits) { +; CHECK-LABEL: test13: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test14(i64 %val, i8 %nbits) { +; CHECK-LABEL: test14: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test15(i64 %val, i8 %nbits) { +; CHECK-LABEL: test15: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: add w8, w8, #255 // =255 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i8 + ret i8 %tmp6 +} + +define i16 @test16(i32 %val, i16 %nbits) { +; CHECK-LABEL: test16: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test17(i32 %val, i16 %nbits) { +; CHECK-LABEL: test17: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test18(i32 %val, i32 %nbits) { +; CHECK-LABEL: test18: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, 65535 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test19(i32 %val, i32 %nbits) { +; CHECK-LABEL: test19: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i32 1, %nbits + %tmp2 = add i32 %tmp, 65535 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test20(i32 %val, i8 %nbits) { +; CHECK-LABEL: test20: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test21(i32 %val, i8 %nbits) { +; CHECK-LABEL: test21: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test22(i64 %val, i16 %nbits) { +; CHECK-LABEL: test22: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test23(i64 %val, i16 %nbits) { +; CHECK-LABEL: test23: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test24(i64 %val, i32 %nbits) { +; CHECK-LABEL: test24: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test25(i64 %val, i32 %nbits) { +; CHECK-LABEL: test25: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test26(i64 %val, i64 %nbits) { +; CHECK-LABEL: test26: +; CHECK: // %bb.0: +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 65535 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test27(i64 %val, i64 %nbits) { +; CHECK-LABEL: test27: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 65535 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test28(i64 %val, i8 %nbits) { +; CHECK-LABEL: test28: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test29(i64 %val, i8 %nbits) { +; CHECK-LABEL: test29: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test30(i64 %val, i8 %nbits) { +; CHECK-LABEL: test30: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: eor w8, w8, #0xffff +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test31(i64 %val, i8 %nbits) { +; CHECK-LABEL: test31: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: add w8, w8, w9 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i16 + ret i16 %tmp6 +} + +define i32 @test32(i32 %val, i32 %nbits) { +; CHECK-LABEL: test32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, -1 + %tmp3 = and i32 %tmp2, %val + ret i32 %tmp3 +} + +define i32 @test33(i32 %val, i32 %nbits) { +; CHECK-LABEL: test33: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i32 1, %nbits + %tmp2 = add i32 %tmp, -1 + %tmp3 = and i32 %tmp2, %val + ret i32 %tmp3 +} + +define i32 @test34(i32 %val, i8 %nbits) { +; CHECK-LABEL: test34: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %val + ret i32 %tmp4 +} + +define i32 @test35(i32 %val, i8 %nbits) { +; CHECK-LABEL: test35: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %val + ret i32 %tmp4 +} + +define i32 @test36(i64 %val, i32 %nbits) { +; CHECK-LABEL: test36: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %tmp + ret i32 %tmp4 +} + +define i32 @test37(i64 %val, i32 %nbits) { +; CHECK-LABEL: test37: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %tmp + ret i32 %tmp4 +} + +define i32 @test38(i64 %val, i64 %nbits) { +; CHECK-LABEL: test38: +; CHECK: // %bb.0: +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 4294967295 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i32 + ret i32 %tmp4 +} + +define i32 @test39(i64 %val, i64 %nbits) { +; CHECK-LABEL: test39: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 4294967295 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i32 + ret i32 %tmp4 +} + +define i32 @test40(i64 %val, i8 %nbits) { +; CHECK-LABEL: test40: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, -1 + %tmp5 = and i32 %tmp4, %tmp + ret i32 %tmp5 +} + +define i32 @test41(i64 %val, i8 %nbits) { +; CHECK-LABEL: test41: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add nsw i32 %tmp3, -1 + %tmp5 = and i32 %tmp4, %tmp + ret i32 %tmp5 +} + +define i32 @test42(i64 %val, i8 %nbits) { +; CHECK-LABEL: test42: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: bic w0, w0, w8 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = trunc i64 %val to i32 + %tmp5 = and i32 %tmp3, %tmp4 + ret i32 %tmp5 +} + +define i32 @test43(i64 %val, i8 %nbits) { +; CHECK-LABEL: test43: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: and w0, w8, w0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = trunc i64 %val to i32 + %tmp5 = and i32 %tmp3, %tmp4 + ret i32 %tmp5 +} + +define i64 @test44(i64 %val, i64 %nbits) { +; CHECK-LABEL: test44: +; CHECK: // %bb.0: +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: bic x0, x0, x8 +; CHECK-NEXT: ret + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, -1 + %tmp3 = and i64 %tmp2, %val + ret i64 %tmp3 +} + +define i64 @test45(i64 %val, i64 %nbits) { +; CHECK-LABEL: test45: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl x8, x8, x1 +; CHECK-NEXT: sub x8, x8, #1 // =1 +; CHECK-NEXT: and x0, x8, x0 +; CHECK-NEXT: ret + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, -1 + %tmp3 = and i64 %tmp2, %val + ret i64 %tmp3 +} + +define i64 @test46(i64 %val, i8 %nbits) { +; CHECK-LABEL: test46: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: mvn w8, w8 +; CHECK-NEXT: sxtw x8, w8 +; CHECK-NEXT: and x0, x8, x0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = sext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + ret i64 %tmp5 +} + +define i64 @test47(i64 %val, i8 %nbits) { +; CHECK-LABEL: test47: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 +; CHECK-NEXT: lsl w8, w8, w1 +; CHECK-NEXT: sub w8, w8, #1 // =1 +; CHECK-NEXT: sxtw x8, w8 +; CHECK-NEXT: and x0, x8, x0 +; CHECK-NEXT: ret + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = sext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + ret i64 %tmp5 +} Index: test/CodeGen/AArch64/set-lowbits-mask.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/set-lowbits-mask.ll @@ -0,0 +1,83 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s + +; https://bugs.llvm.org/show_bug.cgi?id=37603 + +; Patterns: +; (1 << nbits) - 1 +; ~(-(1 << nbits)) +; Are equivalent. + +define i16 @add16(i16 %nbits) { +; CHECK-LABEL: add16: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: lsl w8, w8, w0 +; CHECK-NEXT: sub w0, w8, #1 // =1 +; CHECK-NEXT: ret + %setbit = shl i16 1, %nbits + %ret = add i16 %setbit, -1 + ret i16 %ret +} + +define i32 @add32(i32 %nbits) { +; CHECK-LABEL: add32: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl w8, w8, w0 +; CHECK-NEXT: sub w0, w8, #1 // =1 +; CHECK-NEXT: ret + %setbit = shl i32 1, %nbits + %ret = add i32 %setbit, -1 + ret i32 %ret +} + +define i64 @add64(i64 %nbits) { +; CHECK-LABEL: add64: +; CHECK: // %bb.0: +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: lsl x8, x8, x0 +; CHECK-NEXT: sub x0, x8, #1 // =1 +; CHECK-NEXT: ret + %setbit = shl i64 1, %nbits + %ret = add i64 %setbit, -1 + ret i64 %ret +} + +define i16 @xor16(i16 %nbits) { +; CHECK-LABEL: xor16: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-NEXT: lsl w8, w8, w0 +; CHECK-NEXT: mvn w0, w8 +; CHECK-NEXT: ret + %notmask = shl i16 -1, %nbits + %ret = xor i16 %notmask, -1 + ret i16 %ret +} + +define i32 @xor32(i32 %nbits) { +; CHECK-LABEL: xor32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: lsl w8, w8, w0 +; CHECK-NEXT: mvn w0, w8 +; CHECK-NEXT: ret + %notmask = shl i32 -1, %nbits + %ret = xor i32 %notmask, -1 + ret i32 %ret +} + +define i64 @xor64(i64 %nbits) { +; CHECK-LABEL: xor64: +; CHECK: // %bb.0: +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: lsl x8, x8, x0 +; CHECK-NEXT: mvn x0, x8 +; CHECK-NEXT: ret + %notmask = shl i64 -1, %nbits + %ret = xor i64 %notmask, -1 + ret i64 %ret +} Index: test/CodeGen/X86/get-lowbits.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/get-lowbits.ll @@ -0,0 +1,1635 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-NOBMI +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BMI,CHECK-BMI1 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BMI,CHECK-BMI2 + +; https://bugs.llvm.org/show_bug.cgi?id=36419 +; https://bugs.llvm.org/show_bug.cgi?id=37603 +; https://bugs.llvm.org/show_bug.cgi?id=37610 + +; Patterns: +; (1 << nbits) - 1 +; ~(-(1 << nbits)) +; Are equivalent. + +define i8 @test0(i32 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test0: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test0: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test1(i32 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test1: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test1: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test1: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test2(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test2: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test2: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, 255 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test3(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test3: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test3: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test3: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = add i32 %tmp, 255 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test4(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test4: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test4: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test5(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test5: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test5: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test5: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test6(i64 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test6: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test6: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test7(i64 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test7: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test7: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test7: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test8(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test8: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test8: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test9(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test9: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test9: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test9: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, 255 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i8 + ret i8 %tmp5 +} + +define i8 @test10(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test10: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movq $-1, %rax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test10: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movq $-1, %rax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test10: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movq $-1, %rax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 255 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test11(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test11: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test11: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test11: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: andl %edi, %eax +; CHECK-BMI2-NEXT: # kill: def $al killed $al killed $rax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 255 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i8 + ret i8 %tmp4 +} + +define i8 @test12(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test12: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test12: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test13(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test13: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test13: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test13: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 255 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test14(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test14: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test14: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $al killed $al killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 255 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i8 + ret i8 %tmp6 +} + +define i8 @test15(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test15: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test15: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $al killed $al killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test15: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 255 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i8 + ret i8 %tmp6 +} + +define i16 @test16(i32 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test16: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test16: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i16 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test17(i32 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test17: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test17: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test17: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test18(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test18: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test18: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, 65535 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test19(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test19: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test19: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test19: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = add i32 %tmp, 65535 + %tmp3 = and i32 %tmp2, %val + %tmp4 = trunc i32 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test20(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test20: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test20: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test21(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test21: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test21: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test21: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %val + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test22(i64 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test22: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test22: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test23(i64 %val, i16 %nbits) { +; CHECK-NOBMI-LABEL: test23: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test23: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test23: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = zext i16 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test24(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test24: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test24: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test25(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test25: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test25: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test25: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = and i32 %tmp3, %tmp + %tmp5 = trunc i32 %tmp4 to i16 + ret i16 %tmp5 +} + +define i16 @test26(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test26: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movq $-1, %rax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test26: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movq $-1, %rax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test26: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movq $-1, %rax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 65535 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test27(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test27: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test27: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test27: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: andl %edi, %eax +; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $rax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 65535 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i16 + ret i16 %tmp4 +} + +define i16 @test28(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test28: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test28: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test29(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test29: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test29: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test29: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add i32 %tmp3, 65535 + %tmp5 = and i32 %tmp4, %tmp + %tmp6 = trunc i32 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test30(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test30: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test30: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; 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: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, 65535 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i16 + ret i16 %tmp6 +} + +define i16 @test31(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test31: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test31: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test31: +; CHECK-BMI2: # %bb.0: +; 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 + %tmp2 = shl i32 1, %tmp + %tmp3 = add i32 %tmp2, 65535 + %tmp4 = zext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + %tmp6 = trunc i64 %tmp5 to i16 + ret i16 %tmp6 +} + +define i32 @test32(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test32: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test32: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; 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: retq + %tmp = shl i32 -1, %nbits + %tmp2 = xor i32 %tmp, -1 + %tmp3 = and i32 %tmp2, %val + ret i32 %tmp3 +} + +define i32 @test33(i32 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test33: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test33: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test33: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i32 1, %nbits + %tmp2 = add i32 %tmp, -1 + %tmp3 = and i32 %tmp2, %val + ret i32 %tmp3 +} + +define i32 @test34(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test34: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test34: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; 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: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %val + ret i32 %tmp4 +} + +define i32 @test35(i32 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test35: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test35: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test35: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %val + ret i32 %tmp4 +} + +define i32 @test36(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test36: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test36: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; 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: retq + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 -1, %nbits + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %tmp + ret i32 %tmp4 +} + +define i32 @test37(i64 %val, i32 %nbits) { +; CHECK-NOBMI-LABEL: test37: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test37: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test37: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = shl i32 1, %nbits + %tmp3 = add i32 %tmp2, -1 + %tmp4 = and i32 %tmp3, %tmp + ret i32 %tmp4 +} + +define i32 @test38(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test38: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movq $-1, %rax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test38: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movq $-1, %rax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test38: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movq $-1, %rax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, 4294967295 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i32 + ret i32 %tmp4 +} + +define i32 @test39(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test39: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test39: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test39: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: andl %edi, %eax +; CHECK-BMI2-NEXT: # kill: def $eax killed $eax killed $rax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, 4294967295 + %tmp3 = and i64 %tmp2, %val + %tmp4 = trunc i64 %tmp3 to i32 + ret i32 %tmp4 +} + +define i32 @test40(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test40: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test40: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; 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: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 -1, %tmp2 + %tmp4 = xor i32 %tmp3, -1 + %tmp5 = and i32 %tmp4, %tmp + ret i32 %tmp5 +} + +define i32 @test41(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test41: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test41: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test41: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax +; CHECK-BMI2-NEXT: retq + %tmp = trunc i64 %val to i32 + %tmp2 = zext i8 %nbits to i32 + %tmp3 = shl i32 1, %tmp2 + %tmp4 = add nsw i32 %tmp3, -1 + %tmp5 = and i32 %tmp4, %tmp + ret i32 %tmp5 +} + +define i32 @test42(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test42: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test42: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: andnl %edi, %eax, %eax +; CHECK-BMI1-NEXT: retq +; +; 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: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = trunc i64 %val to i32 + %tmp5 = and i32 %tmp3, %tmp4 + ret i32 %tmp5 +} + +define i32 @test43(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test43: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: andl %edi, %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test43: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: andl %edi, %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test43: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhil %esi, %edi, %eax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = trunc i64 %val to i32 + %tmp5 = and i32 %tmp3, %tmp4 + ret i32 %tmp5 +} + +define i64 @test44(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test44: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movq $-1, %rax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: notq %rax +; CHECK-NOBMI-NEXT: andq %rdi, %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test44: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movq $-1, %rax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: andnq %rdi, %rax, %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test44: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movq $-1, %rax +; CHECK-BMI2-NEXT: shlxq %rsi, %rax, %rax +; CHECK-BMI2-NEXT: andnq %rdi, %rax, %rax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 -1, %nbits + %tmp2 = xor i64 %tmp, -1 + %tmp3 = and i64 %tmp2, %val + ret i64 %tmp3 +} + +define i64 @test45(i64 %val, i64 %nbits) { +; CHECK-NOBMI-LABEL: test45: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: decq %rax +; CHECK-NOBMI-NEXT: andq %rdi, %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test45: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: decq %rax +; CHECK-BMI1-NEXT: andq %rdi, %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test45: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: bzhiq %rsi, %rdi, %rax +; CHECK-BMI2-NEXT: retq + %tmp = shl i64 1, %nbits + %tmp2 = add i64 %tmp, -1 + %tmp3 = and i64 %tmp2, %val + ret i64 %tmp3 +} + +define i64 @test46(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test46: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: cltq +; CHECK-NOBMI-NEXT: andq %rdi, %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test46: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: notl %eax +; CHECK-BMI1-NEXT: cltq +; CHECK-BMI1-NEXT: andq %rdi, %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test46: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $-1, %eax +; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax +; CHECK-BMI2-NEXT: notl %eax +; CHECK-BMI2-NEXT: cltq +; CHECK-BMI2-NEXT: andq %rdi, %rax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 -1, %tmp + %tmp3 = xor i32 %tmp2, -1 + %tmp4 = sext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + ret i64 %tmp5 +} + +define i64 @test47(i64 %val, i8 %nbits) { +; CHECK-NOBMI-LABEL: test47: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %esi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: cltq +; CHECK-NOBMI-NEXT: andq %rdi, %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: test47: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %esi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: cltq +; CHECK-BMI1-NEXT: andq %rdi, %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: test47: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxl %esi, %eax, %eax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: cltq +; CHECK-BMI2-NEXT: andq %rdi, %rax +; CHECK-BMI2-NEXT: retq + %tmp = zext i8 %nbits to i32 + %tmp2 = shl i32 1, %tmp + %tmp3 = add nsw i32 %tmp2, -1 + %tmp4 = sext i32 %tmp3 to i64 + %tmp5 = and i64 %tmp4, %val + ret i64 %tmp5 +} Index: test/CodeGen/X86/set-lowbits-mask.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/set-lowbits-mask.ll @@ -0,0 +1,185 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-NOBMI +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BMI,CHECK-BMI1 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BMI,CHECK-BMI2 + +; https://bugs.llvm.org/show_bug.cgi?id=37603 + +; Patterns: +; (1 << nbits) - 1 +; ~(-(1 << nbits)) +; Are equivalent. + +define i16 @add16(i16 %nbits) { +; CHECK-NOBMI-LABEL: add16: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: add16: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: add16: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxl %edi, %eax, %eax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %setbit = shl i16 1, %nbits + %ret = add i16 %setbit, -1 + ret i16 %ret +} + +define i32 @add32(i32 %nbits) { +; CHECK-NOBMI-LABEL: add32: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: decl %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: add32: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: decl %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: add32: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxl %edi, %eax, %eax +; CHECK-BMI2-NEXT: decl %eax +; CHECK-BMI2-NEXT: retq + %setbit = shl i32 1, %nbits + %ret = add i32 %setbit, -1 + ret i32 %ret +} + +define i64 @add64(i64 %nbits) { +; CHECK-NOBMI-LABEL: add64: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $1, %eax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: decq %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: add64: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $1, %eax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: decq %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: add64: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $1, %eax +; CHECK-BMI2-NEXT: shlxq %rdi, %rax, %rax +; CHECK-BMI2-NEXT: decq %rax +; CHECK-BMI2-NEXT: retq + %setbit = shl i64 1, %nbits + %ret = add i64 %setbit, -1 + ret i64 %ret +} + +define i16 @xor16(i16 %nbits) { +; CHECK-NOBMI-LABEL: xor16: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: xor16: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: notl %eax +; CHECK-BMI1-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: xor16: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $-1, %eax +; CHECK-BMI2-NEXT: shlxl %edi, %eax, %eax +; CHECK-BMI2-NEXT: notl %eax +; CHECK-BMI2-NEXT: # kill: def $ax killed $ax killed $eax +; CHECK-BMI2-NEXT: retq + %notmask = shl i16 -1, %nbits + %ret = xor i16 %notmask, -1 + ret i16 %ret +} + +define i32 @xor32(i32 %nbits) { +; CHECK-NOBMI-LABEL: xor32: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movl $-1, %eax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shll %cl, %eax +; CHECK-NOBMI-NEXT: notl %eax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: xor32: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movl $-1, %eax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shll %cl, %eax +; CHECK-BMI1-NEXT: notl %eax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: xor32: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movl $-1, %eax +; CHECK-BMI2-NEXT: shlxl %edi, %eax, %eax +; CHECK-BMI2-NEXT: notl %eax +; CHECK-BMI2-NEXT: retq + %notmask = shl i32 -1, %nbits + %ret = xor i32 %notmask, -1 + ret i32 %ret +} + +define i64 @xor64(i64 %nbits) { +; CHECK-NOBMI-LABEL: xor64: +; CHECK-NOBMI: # %bb.0: +; CHECK-NOBMI-NEXT: movq $-1, %rax +; CHECK-NOBMI-NEXT: movl %edi, %ecx +; CHECK-NOBMI-NEXT: shlq %cl, %rax +; CHECK-NOBMI-NEXT: notq %rax +; CHECK-NOBMI-NEXT: retq +; +; CHECK-BMI1-LABEL: xor64: +; CHECK-BMI1: # %bb.0: +; CHECK-BMI1-NEXT: movq $-1, %rax +; CHECK-BMI1-NEXT: movl %edi, %ecx +; CHECK-BMI1-NEXT: shlq %cl, %rax +; CHECK-BMI1-NEXT: notq %rax +; CHECK-BMI1-NEXT: retq +; +; CHECK-BMI2-LABEL: xor64: +; CHECK-BMI2: # %bb.0: +; CHECK-BMI2-NEXT: movq $-1, %rax +; CHECK-BMI2-NEXT: shlxq %rdi, %rax, %rax +; CHECK-BMI2-NEXT: notq %rax +; CHECK-BMI2-NEXT: retq + %notmask = shl i64 -1, %nbits + %ret = xor i64 %notmask, -1 + ret i64 %ret +}