diff --git a/llvm/lib/Target/CSKY/CSKYInstrInfo.td b/llvm/lib/Target/CSKY/CSKYInstrInfo.td --- a/llvm/lib/Target/CSKY/CSKYInstrInfo.td +++ b/llvm/lib/Target/CSKY/CSKYInstrInfo.td @@ -158,6 +158,30 @@ let DecoderMethod = "decodeImmShiftOpValue"; } +// Optimize (or x, imm) to (BSETI x, log2(imm)). We should exclude the +// case can be opimized to (ORI32/ORI16 x, imm). +def imm32_1_pop_bit_XFORM : SDNodeXFormgetZExtValue(); + return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N), + N->getValueType(0)); +}]>; +def imm32_1_pop_bit : PatLeaf<(imm), [{ + uint32_t I = N->getZExtValue(); + return llvm::popcount(I) == 1 && I > 0xffff; +}]>; + +// Optimize (and x, imm) to (BCLRI x, log2(~imm)). We should exclude the +// case can be opimized to (ANDNI x, ~imm). +def imm32_1_zero_bit_XFORM : SDNodeXFormgetZExtValue(); + return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N), + N->getValueType(0)); +}]>; +def imm32_1_zero_bit : PatLeaf<(imm), [{ + uint32_t I = ~N->getZExtValue(); + return llvm::popcount(I) == 1 && I > 0xfff; +}]>; + def CSKYSymbol : AsmOperandClass { let Name = "CSKYSymbol"; let RenderMethod = "addImmOperands"; @@ -1422,6 +1446,14 @@ def : Pat<(i32 imm:$imm), (ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>; +// Bit operations. +let Predicates = [iHasE2] in { + def : Pat<(or GPR:$rs, imm32_1_pop_bit:$imm), + (BSETI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$imm))>; + def : Pat<(and GPR:$rs, imm32_1_zero_bit:$imm), + (BCLRI32 GPR:$rs, (imm32_1_zero_bit_XFORM imm32_1_zero_bit:$imm))>; +} + // Other operations. let Predicates = [iHasE2] in { def : Pat<(rotl GPR:$rs1, GPR:$rs2), diff --git a/llvm/test/CodeGen/CSKY/bseti_bclri.ll b/llvm/test/CodeGen/CSKY/bseti_bclri.ll --- a/llvm/test/CodeGen/CSKY/bseti_bclri.ll +++ b/llvm/test/CodeGen/CSKY/bseti_bclri.ll @@ -13,8 +13,7 @@ define i32 @test_or_131072(i32 noundef %0) { ; CHECK-LABEL: test_or_131072: ; CHECK: # %bb.0: -; CHECK-NEXT: movih32 a1, 2 -; CHECK-NEXT: or16 a0, a1 +; CHECK-NEXT: bseti16 a0, 17 ; CHECK-NEXT: rts16 %2 = or i32 %0, 131072 ret i32 %2 @@ -71,9 +70,7 @@ define i32 @test_andnot_131072(i32 noundef %0) { ; CHECK-LABEL: test_andnot_131072: ; CHECK: # %bb.0: -; CHECK-NEXT: movih32 a1, 65533 -; CHECK-NEXT: ori32 a1, a1, 65535 -; CHECK-NEXT: and16 a0, a1 +; CHECK-NEXT: bclri16 a0, 17 ; CHECK-NEXT: rts16 %2 = and i32 %0, -131073 ret i32 %2