
Generate QC_INSB/QC_INSBI from `or (and X, MaskImm), OrImm` iff the value being inserted only sets known zero bits. This is based on a similar DAG to DAG transform done in `AArch64`.
347 lines
9.5 KiB
LLVM
347 lines
9.5 KiB
LLVM
; 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
|
|
}
|