[libc-commits] [libc] [llvm] [LoongArch] Support ISD::SET_ROUNDING (llvm.set.rounding) (PR #205051)

Zhaoxin Yang via libc-commits libc-commits at lists.llvm.org
Mon Jun 22 05:44:03 PDT 2026


================
@@ -4015,6 +4018,31 @@ SDValue LoongArchTargetLowering::lowerATOMIC_FENCE(SDValue Op,
   return Op;
 }
 
+SDValue LoongArchTargetLowering::lowerSET_ROUNDING(SDValue Op,
+                                                   SelectionDAG &DAG) const {
+  MVT GRLenVT = Subtarget.getGRLenVT();
+  SDLoc DL(Op);
+  SDValue Chain = Op.getOperand(0);
+  SDValue RMValue = Op.getOperand(1);
+
+  // Zero-extend i32 rounding mode to GRLenVT.
+  RMValue = DAG.getNode(ISD::ZERO_EXTEND, DL, GRLenVT, RMValue);
+
+  // The rounding mode in FCSR0 occupies bits 1:0.
+  // LLVM rounding mode encoding (0=RNE,1=RTZ,2=RDN,3=RUP) matches
+  // the LoongArch FCSR hardware encoding, so no translation needed.
+  // We mask to 2 bits to guard against invalid values.
+  RMValue = DAG.getNode(ISD::AND, DL, GRLenVT, RMValue,
+                        DAG.getConstant(0x3, DL, GRLenVT));
+
+  // Build MachineInstr node for WRFCSR (pseudo for MOVGR2FCSR).
+  // WRFCSR takes (uimm2:$fcsr, GPR:$src).
+  SDValue FCSRNo = DAG.getTargetConstant(0, DL, GRLenVT); // FCSR0
+  MachineSDNode *RN = DAG.getMachineNode(LoongArch::WRFCSR, DL, MVT::Other,
----------------
ylzsx wrote:

Directly writing FCSR0 may clobber unrelated fields in FCSR. According to https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#definitions-of-fcsr0-register-fields, FCSR3 is an alias of the RM field.

https://github.com/llvm/llvm-project/pull/205051


More information about the libc-commits mailing list