; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32I ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibm -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32IXQCIBM ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibm,+zbs -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32IXQCIBMZBS define i32 @test_ori(i32 %a) nounwind { ; RV32I-LABEL: test_ori: ; RV32I: # %bb.0: ; RV32I-NEXT: ori a0, a0, 511 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_ori: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: ori a0, a0, 511 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_ori: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: ori a0, a0, 511 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %a, 511 ret i32 %or } define i32 @test_insbi_mask(i32 %a) nounwind { ; RV32I-LABEL: test_insbi_mask: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 16 ; RV32I-NEXT: addi a1, a1, -1 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_insbi_mask: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, -1, 16, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_insbi_mask: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, -1, 16, 0 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %a, 65535 ret i32 %or } define i32 @test_insbi_mask_mv(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: test_insbi_mask_mv: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a0, 16 ; RV32I-NEXT: addi a0, a0, -1 ; RV32I-NEXT: or a0, a1, a0 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_insbi_mask_mv: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: mv a0, a1 ; RV32IXQCIBM-NEXT: qc.insbi a0, -1, 16, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_insbi_mask_mv: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: mv a0, a1 ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, -1, 16, 0 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %b, 65535 ret i32 %or } define i32 @test_insbi_shifted_mask(i32 %a) nounwind { ; RV32I-LABEL: test_insbi_shifted_mask: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 15 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_insbi_shifted_mask: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, -1, 4, 12 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_insbi_shifted_mask: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, -1, 4, 12 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %a, 61440 ret i32 %or } define i32 @test_insbi_shifted_mask_multiple_uses(i32 %a) nounwind { ; RV32I-LABEL: test_insbi_shifted_mask_multiple_uses: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 15 ; RV32I-NEXT: or a1, a0, a1 ; RV32I-NEXT: addi a0, a0, 10 ; RV32I-NEXT: xor a0, a1, a0 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_insbi_shifted_mask_multiple_uses: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: lui a1, 15 ; RV32IXQCIBM-NEXT: or a1, a1, a0 ; RV32IXQCIBM-NEXT: addi a0, a0, 10 ; RV32IXQCIBM-NEXT: xor a0, a0, a1 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_insbi_shifted_mask_multiple_uses: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: lui a1, 15 ; RV32IXQCIBMZBS-NEXT: or a1, a1, a0 ; RV32IXQCIBMZBS-NEXT: addi a0, a0, 10 ; RV32IXQCIBMZBS-NEXT: xor a0, a0, a1 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %a, 61440 %add = add i32 %a, 10 %xor = xor i32 %or, %add ret i32 %xor } define i32 @test_single_bit_set(i32 %a) nounwind { ; RV32I-LABEL: test_single_bit_set: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 1 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test_single_bit_set: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, -1, 1, 12 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test_single_bit_set: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: bseti a0, a0, 12 ; RV32IXQCIBMZBS-NEXT: ret %or = or i32 %a, 4096 ret i32 %or } ; Tests for INSB(I) generation from OR and AND define i32 @test1(i32 %a) { ; RV32I-LABEL: test1: ; RV32I: # %bb.0: ; RV32I-NEXT: andi a0, a0, -16 ; RV32I-NEXT: addi a0, a0, 5 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test1: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, 5, 4, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test1: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, 5, 4, 0 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i32 %a, -16 ; 0xfffffff0 %2 = or i32 %1, 5 ; 0x00000005 ret i32 %2 } define i32 @test2(i32 %a) { ; RV32I-LABEL: test2: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 1033216 ; RV32I-NEXT: addi a1, a1, -1 ; RV32I-NEXT: and a0, a0, a1 ; RV32I-NEXT: lui a1, 10240 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test2: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, 10, 4, 22 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test2: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, 10, 4, 22 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i32 %a, -62914561 ; 0xfc3fffff %2 = or i32 %1, 41943040 ; 0x02800000 ret i32 %2 } define i64 @test3(i64 %a) { ; RV32I-LABEL: test3: ; RV32I: # %bb.0: ; RV32I-NEXT: andi a0, a0, -8 ; RV32I-NEXT: addi a0, a0, 5 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test3: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, 5, 3, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test3: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, 5, 3, 0 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i64 %a, -8 ; 0xfffffffffffffff8 %2 = or i64 %1, 5 ; 0x0000000000000005 ret i64 %2 } define i64 @test4(i64 %a) { ; RV32I-LABEL: test4: ; RV32I: # %bb.0: ; RV32I-NEXT: andi a0, a0, -255 ; RV32I-NEXT: addi a0, a0, 18 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test4: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, 9, 7, 1 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test4: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, 9, 7, 1 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i64 %a, -255 ; 0xffffffffffffff01 %2 = or i64 %1, 18 ; 0x0000000000000012 ret i64 %2 } define i32 @test5(i32 %a) { ; RV32I-LABEL: test5: ; RV32I: # %bb.0: ; RV32I-NEXT: andi a0, a0, -16 ; RV32I-NEXT: addi a0, a0, 6 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test5: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: qc.insbi a0, 6, 4, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test5: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: qc.insbi a0, 6, 4, 0 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i32 %a, 4294967280 ; 0xfffffff0 %2 = or i32 %1, 6 ; 0x00000006 ret i32 %2 } define i32 @test6(i32 %a) { ; RV32I-LABEL: test6: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 1048320 ; RV32I-NEXT: and a0, a0, a1 ; RV32I-NEXT: lui a1, 182 ; RV32I-NEXT: addi a1, a1, -1326 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test6: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: lui a1, 182 ; RV32IXQCIBM-NEXT: addi a1, a1, -1326 ; RV32IXQCIBM-NEXT: qc.insb a0, a1, 20, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test6: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: lui a1, 182 ; RV32IXQCIBMZBS-NEXT: addi a1, a1, -1326 ; RV32IXQCIBMZBS-NEXT: qc.insb a0, a1, 20, 0 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i32 %a, 4293918720 ; 0xfff00000 %2 = or i32 %1, 744146 ; 0x000b5ad2 ret i32 %2 } define i32 @test7(i32 %a) { ; RV32I-LABEL: test7: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a1, 1048320 ; RV32I-NEXT: addi a1, a1, 1 ; RV32I-NEXT: and a0, a0, a1 ; RV32I-NEXT: lui a1, 182 ; RV32I-NEXT: addi a1, a1, -1326 ; RV32I-NEXT: or a0, a0, a1 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test7: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: lui a1, 91 ; RV32IXQCIBM-NEXT: addi a1, a1, -663 ; RV32IXQCIBM-NEXT: qc.insb a0, a1, 19, 1 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test7: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: lui a1, 91 ; RV32IXQCIBMZBS-NEXT: addi a1, a1, -663 ; RV32IXQCIBMZBS-NEXT: qc.insb a0, a1, 19, 1 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i32 %a, 4293918721 ; 0xfff00001 %2 = or i32 %1, 744146 ; 0x000b5ad2 ret i32 %2 } define i64 @test8(i64 %a) { ; RV32I-LABEL: test8: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a2, 1044480 ; RV32I-NEXT: zext.b a0, a0 ; RV32I-NEXT: and a1, a1, a2 ; RV32I-NEXT: lui a2, 496944 ; RV32I-NEXT: or a0, a0, a2 ; RV32I-NEXT: lui a2, 9 ; RV32I-NEXT: addi a2, a2, -170 ; RV32I-NEXT: or a1, a1, a2 ; RV32I-NEXT: ret ; ; RV32IXQCIBM-LABEL: test8: ; RV32IXQCIBM: # %bb.0: ; RV32IXQCIBM-NEXT: lui a2, 1941 ; RV32IXQCIBM-NEXT: addi a2, a2, 768 ; RV32IXQCIBM-NEXT: qc.insb a0, a2, 24, 8 ; RV32IXQCIBM-NEXT: lui a2, 9 ; RV32IXQCIBM-NEXT: addi a2, a2, -170 ; RV32IXQCIBM-NEXT: qc.insb a1, a2, 24, 0 ; RV32IXQCIBM-NEXT: ret ; ; RV32IXQCIBMZBS-LABEL: test8: ; RV32IXQCIBMZBS: # %bb.0: ; RV32IXQCIBMZBS-NEXT: lui a2, 1941 ; RV32IXQCIBMZBS-NEXT: addi a2, a2, 768 ; RV32IXQCIBMZBS-NEXT: qc.insb a0, a2, 24, 8 ; RV32IXQCIBMZBS-NEXT: lui a2, 9 ; RV32IXQCIBMZBS-NEXT: addi a2, a2, -170 ; RV32IXQCIBMZBS-NEXT: qc.insb a1, a2, 24, 0 ; RV32IXQCIBMZBS-NEXT: ret %1 = and i64 %a, -72057594037927681 ; 0xff000000000000ff %2 = or i64 %1, 157601565442048 ; 0x00008f5679530000 ret i64 %2 }