From 9ba808ccd263f4972ef1649fd352398ca9e627d1 Mon Sep 17 00:00:00 2001 From: Jerry Sun Date: Tue, 22 Apr 2025 13:27:04 -0400 Subject: [PATCH] implement backend lowering for cksm instruction --- llvm/include/llvm/IR/IntrinsicsSystemZ.td | 6 ++++++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 12 ++++++++++++ llvm/lib/Target/SystemZ/SystemZISelLowering.h | 8 ++++++++ llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 9 ++++++++- llvm/lib/Target/SystemZ/SystemZOperators.td | 8 ++++++++ llvm/test/CodeGen/SystemZ/cksm-intrinsic-01.ll | 6 ++++++ 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/SystemZ/cksm-intrinsic-01.ll diff --git a/llvm/include/llvm/IR/IntrinsicsSystemZ.td b/llvm/include/llvm/IR/IntrinsicsSystemZ.td index 4f925979cf856..b38e98f8a08b7 100644 --- a/llvm/include/llvm/IR/IntrinsicsSystemZ.td +++ b/llvm/include/llvm/IR/IntrinsicsSystemZ.td @@ -462,3 +462,9 @@ let TargetPrefix = "s390" in { def int_s390_tdc : Intrinsic<[llvm_i32_ty], [llvm_anyfloat_ty, llvm_i64_ty], [IntrNoMem]>; } + +let TargetPrefix = "s390" in { + def int_s390_cksm : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_i64_ty], + [llvm_i32_ty], + [IntrReadMem]>; +} diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 59154431877a8..a5adf23ebcb00 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -362,6 +362,18 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { return; } + case SystemZ::CKSMLoop: { + MCSymbol *DotSym = OutContext.createTempSymbol(); + OutStreamer->emitLabel(DotSym); + EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::CKSM)) + .addReg(MI->getOperand(1).getReg() + .addReg(MI->getOperand(2).getReg())); + // Emit jo to label + LoweredMI = MCInstBuilder(SystemZ::BRC) + .addImm(MI->getOperand(0).getImm()) + .addImm(MI->getOperand(1).getImm()) + .addExpr(MCSymbolRefExpr::create(DotSym, Outcontext)); + } break; case SystemZ::CallBRASL: LoweredMI = MCInstBuilder(SystemZ::BRASL) .addReg(SystemZ::R14D) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h index 3c06c1fdf2b1b..1bd57538fff2d 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -295,6 +295,14 @@ enum NodeType : unsigned { // Operand 1: the bit mask TDC, + // CheckSum Class + // + // Operand 0: output checksum + // Operand 1: input checksum + // Operand 2: memory of buffer + // Operand 3: length + CKSM, + // z/OS XPLINK ADA Entry // Wraps a TargetGlobalAddress that should be loaded from a function's // AssociatedData Area (ADA). Tha ADA is passed to the function by the diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index 5cbba0d9c5edd..b1d642b9cc31d 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -2103,7 +2103,14 @@ let mayLoad = 1, mayStore = 1, Defs = [CC, R0D, R1D, R2D, R3D, R5D], // Checksum. let mayLoad = 1, Defs = [CC] in - def CKSM : SideEffectBinaryMemMemRRE<"cksm", 0xB241, GR64, GR128>; + def CKSM : SideEffectBinaryMemMemRRE<"cksm", 0xB241, GR32, GR128>; + +let usesCustomInserter = 1, mayLoad = 1, hasNoSchedulingInfo = 1, Defs = [CC] in + def CKSMLoop : Pseudo<(outs GR32:$cksmout), + (ins GR32:cksmin, GR128:$ptr_len)>; + // Look for intrinsic and replace with pseudo instruction + def Pat<(int_s390_cksm GR32:$cksmin, ADDR64:$ptr, GR64:$len), + (CKSMLoop GR32:$cksmin, PAIR128(ADDR64:$ptr, GR64:$len))> // Compression call. let mayLoad = 1, mayStore = 1, Defs = [CC, R1D], Uses = [R0L, R1D] in diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td index 6cb89ccff85e6..cd1376b641735 100644 --- a/llvm/lib/Target/SystemZ/SystemZOperators.td +++ b/llvm/lib/Target/SystemZ/SystemZOperators.td @@ -237,6 +237,11 @@ def SDT_ZVecQuaternaryIntCC : SDTypeProfile<2, 4, def SDT_ZTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<2, i64>]>; +def SDT_ZCKSM : SDTypeProfile<1, 3, + [SDTCisInt<0>, + SDTCisInt<1>, + SDTCisPtrTy<2>, + SDTCisInt<3>]>; //===----------------------------------------------------------------------===// // Node definitions @@ -314,6 +319,9 @@ def z_stckf : SDNode<"SystemZISD::STCKF", SDT_ZStoreInherent, def z_tdc : SDNode<"SystemZISD::TDC", SDT_ZTest>; +def z_cksm : SDNode<"SystemZISD::CKSM", SDT_ZCKSM, + [SDNPHasChain, SDNMayLoad]> + // Defined because the index is an i32 rather than a pointer. def z_vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", SDT_ZInsertVectorElt>; diff --git a/llvm/test/CodeGen/SystemZ/cksm-intrinsic-01.ll b/llvm/test/CodeGen/SystemZ/cksm-intrinsic-01.ll new file mode 100644 index 0000000000000..3b6c5cb3881a4 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/cksm-intrinsic-01.ll @@ -0,0 +1,6 @@ +; RUN llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 --stop-after=systemz-isel | FileCheck %s + +define i32 @get_checksum(i32 %cksmin, ptr %mem, i64 %len) { + %res = call i32 @llvm.s390.cksm(i32 %cksmin, ptr %mem, i64 %len) + ret i32 %res +} \ No newline at end of file