[llvm] aa7fc02 - Recommit "[RISCV] Make the operand order for RISCVISD::FSL(W)/FSR(W) match the instruction register numbering."
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 18 10:52:58 PST 2022
Author: Craig Topper
Date: 2022-01-18T10:52:43-08:00
New Revision: aa7fc02febec17ebc1fd46934ac0c90d31969d5d
URL: https://github.com/llvm/llvm-project/commit/aa7fc02febec17ebc1fd46934ac0c90d31969d5d
DIFF: https://github.com/llvm/llvm-project/commit/aa7fc02febec17ebc1fd46934ac0c90d31969d5d.diff
LOG: Recommit "[RISCV] Make the operand order for RISCVISD::FSL(W)/FSR(W) match the instruction register numbering."
This reverts the revert commit e32838573929ac85fc4df3058593798d10ce4cd2.
Accidental demanded bits change has been removed. The demanded bits
code itself was remove in a pre-commit since it isn't tested.
Original commit message:
Previous we used the fshl/fshr operand ordering for simplicity. This
made things confusing when D117468 proposed adding intrinsics for
the instructions. We can't just use the generic funnel shifting
intrinsics because fsl/fsr have different functionality that should
be exposed to software.
Now we use rs1, rs3, rs2/shamt order which matches the instruction
printing order and the order used in this intrinsic header
https://github.com/riscv/riscv-bitmanip/blob/main-history/cproofs/rvintrin.h
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.h
llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0f8e21914e30..078ce1b5ef5e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2795,12 +2795,24 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
if (Op.getOperand(2).getOpcode() == ISD::Constant)
return Op;
// FSL/FSR take a log2(XLen)+1 bit shift amount but XLenVT FSHL/FSHR only
- // use log(XLen) bits. Mask the shift amount accordingly.
+ // use log(XLen) bits. Mask the shift amount accordingly to prevent
+ // accidentally setting the extra bit.
unsigned ShAmtWidth = Subtarget.getXLen() - 1;
SDValue ShAmt = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(2),
DAG.getConstant(ShAmtWidth, DL, VT));
- unsigned Opc = Op.getOpcode() == ISD::FSHL ? RISCVISD::FSL : RISCVISD::FSR;
- return DAG.getNode(Opc, DL, VT, Op.getOperand(0), Op.getOperand(1), ShAmt);
+ // fshl and fshr concatenate their operands in the same order. fsr and fsl
+ // instruction use
diff erent orders. fshl will return its first operand for
+ // shift of zero, fshr will return its second operand. fsl and fsr both
+ // return rs1 so the ISD nodes need to have
diff erent operand orders.
+ // Shift amount is in rs2.
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+ unsigned Opc = RISCVISD::FSL;
+ if (Op.getOpcode() == ISD::FSHR) {
+ std::swap(Op0, Op1);
+ Opc = RISCVISD::FSR;
+ }
+ return DAG.getNode(Opc, DL, VT, Op0, Op1, ShAmt);
}
case ISD::TRUNCATE: {
SDLoc DL(Op);
@@ -6232,15 +6244,23 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0));
SDValue NewOp1 =
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
- SDValue NewOp2 =
+ SDValue NewShAmt =
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
// FSLW/FSRW take a 6 bit shift amount but i32 FSHL/FSHR only use 5 bits.
- // Mask the shift amount to 5 bits.
- NewOp2 = DAG.getNode(ISD::AND, DL, MVT::i64, NewOp2,
- DAG.getConstant(0x1f, DL, MVT::i64));
- unsigned Opc =
- N->getOpcode() == ISD::FSHL ? RISCVISD::FSLW : RISCVISD::FSRW;
- SDValue NewOp = DAG.getNode(Opc, DL, MVT::i64, NewOp0, NewOp1, NewOp2);
+ // Mask the shift amount to 5 bits to prevent accidentally setting bit 5.
+ NewShAmt = DAG.getNode(ISD::AND, DL, MVT::i64, NewShAmt,
+ DAG.getConstant(0x1f, DL, MVT::i64));
+ // fshl and fshr concatenate their operands in the same order. fsrw and fslw
+ // instruction use
diff erent orders. fshl will return its first operand for
+ // shift of zero, fshr will return its second operand. fsl and fsr both
+ // return rs1 so the ISD nodes need to have
diff erent operand orders.
+ // Shift amount is in rs2.
+ unsigned Opc = RISCVISD::FSLW;
+ if (N->getOpcode() == ISD::FSHR) {
+ std::swap(NewOp0, NewOp1);
+ Opc = RISCVISD::FSRW;
+ }
+ SDValue NewOp = DAG.getNode(Opc, DL, MVT::i64, NewOp0, NewOp1, NewShAmt);
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewOp));
break;
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index cd423c9ecca0..76b778831fae 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -63,11 +63,11 @@ enum NodeType : unsigned {
CLZW,
CTZW,
// RV64IB/RV32IB funnel shifts, with the semantics of the named RISC-V
- // instructions, but the same operand order as fshl/fshr intrinsics.
+ // instructions. Operand order is rs1, rs3, rs2/shamt.
FSR,
FSL,
- // RV64IB funnel shifts, with the semantics of the named RISC-V instructions,
- // but the same operand order as fshl/fshr intrinsics.
+ // RV64IB funnel shifts, with the semantics of the named RISC-V instructions.
+ // Operand order is rs1, rs3, rs2/shamt.
FSRW,
FSLW,
// FPR<->GPR transfer operations when the FPR is smaller than XLEN, needed as
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index c2e7217df30f..74f617c8333a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -901,16 +901,16 @@ def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
(CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
} // Predicates = [HasStdExtZbt]
-// fshl and fshr concatenate their operands in the same order. fsr and fsl
-// instruction use
diff erent orders. fshl will return its first operand for
-// shift of zero, fshr will return its second operand. fsl and fsr both return
-// $rs1 so the patterns need to have
diff erent operand orders.
let Predicates = [HasStdExtZbt] in {
def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
-def : Pat<(riscv_fsr GPR:$rs3, GPR:$rs1, GPR:$rs2),
+def : Pat<(riscv_fsr GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
+// fshl and fshr concatenate their operands in the same order. fsr and fsl
+// instruction use
diff erent orders. fshl will return its first operand for
+// shift of zero, fshr will return its second operand. fsl and fsr both return
+// $rs1 so the patterns need to have
diff erent operand orders.
def : Pat<(fshr GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
(FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
// We can use FSRI for fshl by immediate if we subtract the immediate from
@@ -1090,10 +1090,12 @@ def : PatGprImm<riscv_gorcw, GORCIW, uimm5>;
let Predicates = [HasStdExtZbt, IsRV64] in {
def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
-def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, GPR:$rs2),
+def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, GPR:$rs2),
(FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
-def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
+def : Pat<(riscv_fsrw GPR:$rs1, GPR:$rs3, uimm5:$shamt),
(FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
+// We can use FSRIW for FSLW by immediate if we subtract the immediate from
+// 32 and swap the operands.
def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
(FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
} // Predicates = [HasStdExtZbt, IsRV64]
More information about the llvm-commits
mailing list