[llvm] [X86] Added support for 16bit LEA instruction (PR #122102)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 8 08:13:46 PST 2025


https://github.com/JaydeepChauhan14 updated https://github.com/llvm/llvm-project/pull/122102

>From f9cf1159bdf3c12a610bc07d6b0860496f9659bc Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Wed, 8 Jan 2025 20:33:55 +0800
Subject: [PATCH 1/2] [X86] Added support for 16bit LEA instruction

---
 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp      | 37 ++++++++++++++++++++
 llvm/lib/Target/X86/X86InstrArithmetic.td    |  6 ++++
 llvm/lib/Target/X86/X86InstrFragments.td     |  5 +++
 llvm/lib/Target/X86/X86InstrOperands.td      |  6 ++++
 llvm/test/CodeGen/X86/16bit-lea.ll           | 14 ++++++++
 llvm/utils/TableGen/X86RecognizableInstr.cpp |  2 ++
 6 files changed, 70 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/16bit-lea.ll

diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 9b340a778b36ad..7f33b40503c2c8 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -226,6 +226,8 @@ namespace {
     bool selectLEAAddr(SDValue N, SDValue &Base,
                        SDValue &Scale, SDValue &Index, SDValue &Disp,
                        SDValue &Segment);
+    bool selectLEA64_16Addr(SDValue N, SDValue &Base, SDValue &Scale,
+                            SDValue &Index, SDValue &Disp, SDValue &Segment);
     bool selectLEA64_32Addr(SDValue N, SDValue &Base,
                             SDValue &Scale, SDValue &Index, SDValue &Disp,
                             SDValue &Segment);
@@ -3054,6 +3056,41 @@ bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) {
   return !TM.isLargeGlobalValue(GV);
 }
 
+bool X86DAGToDAGISel::selectLEA64_16Addr(SDValue N, SDValue &Base,
+                                         SDValue &Scale, SDValue &Index,
+                                         SDValue &Disp, SDValue &Segment) {
+  // Save the debug loc before calling selectLEAAddr, in case it invalidates N.
+  SDLoc DL(N);
+
+  if (!selectLEAAddr(N, Base, Scale, Index, Disp, Segment))
+    return false;
+
+  auto *RN = dyn_cast<RegisterSDNode>(Base);
+  if (RN && RN->getReg() == 0)
+    Base = CurDAG->getRegister(0, MVT::i64);
+  else if (Base.getValueType() == MVT::i16 && !isa<FrameIndexSDNode>(Base)) {
+    // Base could already be %rip, particularly in the x32 ABI.
+    SDValue ImplDef =
+        SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, DL, MVT::i64), 0);
+    Base = CurDAG->getTargetInsertSubreg(X86::sub_16bit, DL, MVT::i64, ImplDef,
+                                         Base);
+  }
+
+  RN = dyn_cast<RegisterSDNode>(Index);
+  if (RN && RN->getReg() == 0)
+    Index = CurDAG->getRegister(0, MVT::i64);
+  else {
+    assert(Index.getValueType() == MVT::i16 &&
+           "Expect to be extending 16-bit registers for use in LEA");
+    SDValue ImplDef =
+        SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, DL, MVT::i64), 0);
+    Index = CurDAG->getTargetInsertSubreg(X86::sub_16bit, DL, MVT::i64, ImplDef,
+                                          Index);
+  }
+
+  return true;
+}
+
 bool X86DAGToDAGISel::selectLEA64_32Addr(SDValue N, SDValue &Base,
                                          SDValue &Scale, SDValue &Index,
                                          SDValue &Disp, SDValue &Segment) {
diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 16ca2882a84daf..a72fc02e1ba523 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -25,6 +25,12 @@ let SchedRW = [WriteLEA] in {
                      [(set GR32:$dst, lea32addr:$src)]>,
                      OpSize32, Requires<[Not64BitMode]>;
 
+  def LEA64_16r : I<0x8D, MRMSrcMem, (outs GR16:$dst), (ins lea64_16mem:$src),
+                    "lea{w}\t{$src|$dst}, {$dst|$src}",
+                    [(set GR16:$dst, lea64_16addr:$src)]>,
+                  OpSize16,
+                  Requires<[In64BitMode]>;
+
   def LEA64_32r : I<0x8D, MRMSrcMem,
                     (outs GR32:$dst), (ins lea64_32mem:$src),
                     "lea{l}\t{$src|$dst}, {$dst|$src}",
diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td
index ea7af893ce103f..ada4c29da4a97f 100644
--- a/llvm/lib/Target/X86/X86InstrFragments.td
+++ b/llvm/lib/Target/X86/X86InstrFragments.td
@@ -357,6 +357,11 @@ def addr      : ComplexPattern<iPTR, 5, "selectAddr">;
 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
                                [add, sub, mul, X86mul_imm, shl, or, xor, frameindex],
                                []>;
+// In 64-bit mode 16-bit LEAs can use RIP-relative addressing.
+def lea64_16addr : ComplexPattern<i16, 5, "selectLEA64_16Addr",
+                                  [add, sub, mul, X86mul_imm, shl, or, xor,
+                                   frameindex, X86WrapperRIP],
+                                  []>;
 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
                                   [add, sub, mul, X86mul_imm, shl, or, xor,
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 2102cb4b6b5b73..4bf31c115e635e 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -461,6 +461,12 @@ def i64u8imm : Operand<i64> {
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
+def lea64_16mem : Operand<i16> {
+  let PrintMethod = "printMemReference";
+  let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i16imm, SEGMENT_REG);
+  let ParserMatchClass = X86MemAsmOperand;
+}
+
 def lea64_32mem : Operand<i32> {
   let PrintMethod = "printMemReference";
   let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
diff --git a/llvm/test/CodeGen/X86/16bit-lea.ll b/llvm/test/CodeGen/X86/16bit-lea.ll
new file mode 100644
index 00000000000000..049b216c313fa8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/16bit-lea.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+ndd | FileCheck %s --check-prefixes=CHECK
+
+define dso_local signext range(i16 1, 0) i16 @lea16bit(i16 noundef signext %in) local_unnamed_addr #0 {
+; CHECK-LABEL: lea16bit:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT:    leaw 1(%rdi,%rdi), %ax
+; CHECK-NEXT:    retq
+entry:
+  %shl = shl i16 %in, 1
+  %or = or disjoint i16 %shl, 1
+  ret i16 %or
+}
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index c6cd3da13646a6..af16b3782195b0 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -1096,6 +1096,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("brtarget16", TYPE_REL)
   TYPE("brtarget8", TYPE_REL)
   TYPE("f80mem", TYPE_M)
+  TYPE("lea64_16mem", TYPE_M)
   TYPE("lea64_32mem", TYPE_M)
   TYPE("lea64mem", TYPE_M)
   TYPE("VR64", TYPE_MM64)
@@ -1367,6 +1368,7 @@ RecognizableInstr::memoryEncodingFromString(const std::string &s,
   ENCODING("i512mem_GR32", ENCODING_RM)
   ENCODING("i512mem_GR64", ENCODING_RM)
   ENCODING("f80mem", ENCODING_RM)
+  ENCODING("lea64_16mem", ENCODING_RM)
   ENCODING("lea64_32mem", ENCODING_RM)
   ENCODING("lea64mem", ENCODING_RM)
   ENCODING("anymem", ENCODING_RM)

>From 71c70f206d6ca208f40e45a0b2acc8d520d8563f Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 9 Jan 2025 00:13:14 +0800
Subject: [PATCH 2/2] Addressed the testcase review comments

---
 llvm/test/CodeGen/X86/{16bit-lea.ll => lea-16bit.ll} | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
 rename llvm/test/CodeGen/X86/{16bit-lea.ll => lea-16bit.ll} (73%)

diff --git a/llvm/test/CodeGen/X86/16bit-lea.ll b/llvm/test/CodeGen/X86/lea-16bit.ll
similarity index 73%
rename from llvm/test/CodeGen/X86/16bit-lea.ll
rename to llvm/test/CodeGen/X86/lea-16bit.ll
index 049b216c313fa8..c06fa91b6fe721 100644
--- a/llvm/test/CodeGen/X86/16bit-lea.ll
+++ b/llvm/test/CodeGen/X86/lea-16bit.ll
@@ -1,13 +1,12 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+ndd | FileCheck %s --check-prefixes=CHECK
 
-define dso_local signext range(i16 1, 0) i16 @lea16bit(i16 noundef signext %in) local_unnamed_addr #0 {
+define i16 @lea16bit(i16 %in) {
 ; CHECK-LABEL: lea16bit:
-; CHECK:       # %bb.0: # %entry
+; CHECK:       # %bb.0:
 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
 ; CHECK-NEXT:    leaw 1(%rdi,%rdi), %ax
 ; CHECK-NEXT:    retq
-entry:
   %shl = shl i16 %in, 1
   %or = or disjoint i16 %shl, 1
   ret i16 %or



More information about the llvm-commits mailing list