[llvm] r178526 - Materialize 64-bit immediates.

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon Apr 1 21:09:18 PDT 2013


Author: stoklund
Date: Mon Apr  1 23:09:17 2013
New Revision: 178526

URL: http://llvm.org/viewvc/llvm-project?rev=178526&view=rev
Log:
Materialize 64-bit immediates.

The last resort pattern produces 6 instructions, and there are still
opportunities for materializing some immediates in fewer instructions.

Modified:
    llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
    llvm/trunk/test/CodeGen/SPARC/64bit.ll

Modified: llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td?rev=178526&r1=178525&r2=178526&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td Mon Apr  1 23:09:17 2013
@@ -45,3 +45,91 @@ defm SRLX : F3_S<"srlx", 0b100110, 1, sr
 defm SRAX : F3_S<"srax", 0b100111, 1, sra, i64, I64Regs>;
 
 } // Predicates = [Is64Bit]
+
+
+//===----------------------------------------------------------------------===//
+// 64-bit Immediates.
+//===----------------------------------------------------------------------===//
+//
+// All 32-bit immediates can be materialized with sethi+or, but 64-bit
+// immediates may require more code. There may be a point where it is
+// preferable to use a constant pool load instead, depending on the
+// microarchitecture.
+
+// The %g0 register is constant 0.
+// This is useful for stx %g0, [...], for example.
+def : Pat<(i64 0), (i64 G0)>, Requires<[Is64Bit]>;
+
+// Single-instruction patterns.
+
+// The ALU instructions want their simm13 operands as i32 immediates.
+def as_i32imm : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
+}]>;
+def : Pat<(i64 simm13:$val), (ORri (i64 G0), (as_i32imm $val))>;
+def : Pat<(i64 SETHIimm:$val), (SETHIi (HI22 $val))>;
+
+// Double-instruction patterns.
+
+// All unsigned i32 immediates can be handled by sethi+or.
+def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
+def : Pat<(i64 uimm32:$val), (ORri (SETHIi (HI22 $val)), (LO10 $val))>,
+      Requires<[Is64Bit]>;
+
+// All negative i33 immediates can be handled by sethi+xor.
+def nimm33 : PatLeaf<(imm), [{
+  int64_t Imm = N->getSExtValue();
+  return Imm < 0 && isInt<33>(Imm);
+}]>;
+// Bits 10-31 inverted. Same as assembler's %hix.
+def HIX22 : SDNodeXForm<imm, [{
+  uint64_t Val = (~N->getZExtValue() >> 10) & ((1u << 22) - 1);
+  return CurDAG->getTargetConstant(Val, MVT::i32);
+}]>;
+// Bits 0-9 with ones in bits 10-31. Same as assembler's %lox.
+def LOX10 : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(~(~N->getZExtValue() & 0x3ff), MVT::i32);
+}]>;
+def : Pat<(i64 nimm33:$val), (XORri (SETHIi (HIX22 $val)), (LOX10 $val))>,
+      Requires<[Is64Bit]>;
+
+// More possible patterns:
+//
+//   (sllx sethi, n)
+//   (sllx simm13, n)
+//
+// 3 instrs:
+//
+//   (xor (sllx sethi), simm13)
+//   (sllx (xor sethi, simm13))
+//
+// 4 instrs:
+//
+//   (or sethi, (sllx sethi))
+//   (xnor sethi, (sllx sethi))
+//
+// 5 instrs:
+//
+//   (or (sllx sethi), (or sethi, simm13))
+//   (xnor (sllx sethi), (or sethi, simm13))
+//   (or (sllx sethi), (sllx sethi))
+//   (xnor (sllx sethi), (sllx sethi))
+//
+// Worst case is 6 instrs:
+//
+//   (or (sllx (or sethi, simmm13)), (or sethi, simm13))
+
+// Bits 42-63, same as assembler's %hh.
+def HH22 : SDNodeXForm<imm, [{
+  uint64_t Val = (N->getZExtValue() >> 42) & ((1u << 22) - 1);
+  return CurDAG->getTargetConstant(Val, MVT::i32);
+}]>;
+// Bits 32-41, same as assembler's %hm.
+def HM10 : SDNodeXForm<imm, [{
+  uint64_t Val = (N->getZExtValue() >> 32) & ((1u << 10) - 1);
+  return CurDAG->getTargetConstant(Val, MVT::i32);
+}]>;
+def : Pat<(i64 imm:$val),
+          (ORrr (SLLXri (ORri (SETHIi (HH22 $val)), (HM10 $val)), (i64 32)),
+                (ORri (SETHIi (HI22 $val)), (LO10 $val)))>,
+      Requires<[Is64Bit]>;

Modified: llvm/trunk/test/CodeGen/SPARC/64bit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/64bit.ll?rev=178526&r1=178525&r2=178526&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/64bit.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/64bit.ll Mon Apr  1 23:09:17 2013
@@ -19,3 +19,49 @@ define i64 @sra_reg(i64 %a, i64 %b) {
   %x = ashr i64 %a, %b
   ret i64 %x
 }
+
+; Immediate materialization. Many of these patterns could actually be merged
+; into the restore instruction:
+;
+;     restore %g0, %g0, %o0
+;
+; CHECK: ret_imm0
+; CHECK: or %g0, %g0, %i0
+define i64 @ret_imm0() {
+  ret i64 0
+}
+
+; CHECK: ret_simm13
+; CHECK: or %g0, -4096, %i0
+define i64 @ret_simm13() {
+  ret i64 -4096
+}
+
+; CHECK: ret_sethi
+; CHECK: sethi 4, %i0
+; CHECK-NOT: or
+; CHECK: restore
+define i64 @ret_sethi() {
+  ret i64 4096
+}
+
+; CHECK: ret_sethi
+; CHECK: sethi 4, [[R:%[goli][0-7]]]
+; CHECK: or [[R]], 1, %i0
+define i64 @ret_sethi_or() {
+  ret i64 4097
+}
+
+; CHECK: ret_nimm33
+; CHECK: sethi 4, [[R:%[goli][0-7]]]
+; CHECK: xor [[R]], -4, %i0
+define i64 @ret_nimm33() {
+  ret i64 -4100
+}
+
+; CHECK: ret_bigimm
+; CHECK: sethi
+; CHECK: sethi
+define i64 @ret_bigimm() {
+  ret i64 6800754272627607872
+}





More information about the llvm-commits mailing list