Index: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td @@ -86,6 +86,24 @@ let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; } +// Standalone (codegen-only) immleaf patterns. +def simm32 : ImmLeaf(Imm);}]>; + +// Extract least significant 12 bits from an immediate value and sign extend +// them. +def LO12Sext : SDNodeXFormgetTargetConstant(SignExtend64<12>(N->getZExtValue()), + SDLoc(N), N->getValueType(0)); +}]>; + +// Extract the most significant 20 bits from an immediate value. Add 1 if bit +// 11 is 1, to compensate for the low 12 bits in the matching immediate addi +// or ld/st being negative. +def HI20 : SDNodeXFormgetTargetConstant(((N->getZExtValue()+0x800) >> 12) & 0xfffff, + SDLoc(N), N->getValueType(0)); +}]>; + //===----------------------------------------------------------------------===// // Instruction Class Templates //===----------------------------------------------------------------------===// @@ -257,6 +275,12 @@ : Pat<(OpNode GPR:$rs1, uimm5:$shamt), (Inst GPR:$rs1, uimm5:$shamt)>; +/// Immediates + +def : Pat<(simm12:$imm), (ADDI X0, simm12:$imm)>; +// TODO: Add a pattern for immediates with all zeroes in the lower 12 bits. +def : Pat<(simm32:$imm), (ADDI (LUI (HI20 imm:$imm)), (LO12Sext imm:$imm))>; + /// Simple arithmetic operations def : PatGprGpr; Index: llvm/trunk/test/CodeGen/RISCV/alu32.ll =================================================================== --- llvm/trunk/test/CodeGen/RISCV/alu32.ll +++ llvm/trunk/test/CodeGen/RISCV/alu32.ll @@ -7,7 +7,6 @@ ; RV32I-LABEL: addi: ; RV32I: addi a0, a0, 1 ; RV32I: jalr zero, ra, 0 -; TODO: check support for materialising larger constants %1 = add i32 %a, 1 ret i32 %1 } Index: llvm/trunk/test/CodeGen/RISCV/imm.ll =================================================================== --- llvm/trunk/test/CodeGen/RISCV/imm.ll +++ llvm/trunk/test/CodeGen/RISCV/imm.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32I + +; Materializing constants + +define i32 @zero() nounwind { +; RV32I-LABEL: zero: +; RV32I: # BB#0: +; RV32I-NEXT: addi a0, zero, 0 +; RV32I-NEXT: jalr zero, ra, 0 + ret i32 0 +} + +define i32 @pos_small() nounwind { +; RV32I-LABEL: pos_small: +; RV32I: # BB#0: +; RV32I-NEXT: addi a0, zero, 2047 +; RV32I-NEXT: jalr zero, ra, 0 + ret i32 2047 +} + +define i32 @neg_small() nounwind { +; RV32I-LABEL: neg_small: +; RV32I: # BB#0: +; RV32I-NEXT: addi a0, zero, -2048 +; RV32I-NEXT: jalr zero, ra, 0 + ret i32 -2048 +} + +define i32 @pos_i32() nounwind { +; RV32I-LABEL: pos_i32: +; RV32I: # BB#0: +; RV32I-NEXT: lui a0, 423811 +; RV32I-NEXT: addi a0, a0, -1297 +; RV32I-NEXT: jalr zero, ra, 0 + ret i32 1735928559 +} + +define i32 @neg_i32() nounwind { +; RV32I-LABEL: neg_i32: +; RV32I: # BB#0: +; RV32I-NEXT: lui a0, 912092 +; RV32I-NEXT: addi a0, a0, -273 +; RV32I-NEXT: jalr zero, ra, 0 + ret i32 -559038737 +}