[PATCH] D128911: Emit table lookup from TargetLowering::expandCTTZ()

Shubham Narlawar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 30 07:17:57 PDT 2022


gsocshubham created this revision.
gsocshubham added reviewers: craig.topper, momchil.velikov, greened, efriedma.
Herald added subscribers: StephenFan, fedor.sergeev, hiraditya, jyknight.
Herald added a project: All.
gsocshubham requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This is draft patch to disucss about emitting table lookup in expandCTTZ. The patch is child revision of `https://reviews.llvm.org/D113291`.

Context -

https://reviews.llvm.org/D113291 transforms below IR to cttz intrinsic -

@f.table = internal unnamed_addr constant [32 x i8] c"\00\01\1C\02\1D\0E\18\03\1E\16\14\0F\19\11\04\08\1F\1B\0D\17\15\13\10\07\1A\0C\12\06\0B\05\0A\09", align 1

define i32 @f(i32 %x) {
entry:

  %sub = sub i32 0, %x
  %and = and i32 %sub, %x
  %mul = mul i32 %and, 125613361
  %shr = lshr i32 %mul, 27
  %idxprom = zext i32 %shr to i64
  %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @f.table, i64 0, i64 %idxprom
  %0 = load i8, i8* %arrayidx, align 1
  %conv = zext i8 %0 to i32
  ret i32 %conv

}

transforms into -

f.table = internal unnamed_addr constant [32 x i8] c"\00\01\1C\02\1D\0E\18\03\1E\16\14\0F\19\11\04\08\1F\1B\0D\17\15\13\10\07\1A\0C\12\06\0B\05\0A\09", align 1

define i32 @f(i32 %x) {
entry:

  %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
  %1 = icmp eq i32 %x, 0
  %2 = select i1 %1, i32 0, i32 %0
  %3 = trunc i32 %2 to i8
  %conv = zext i8 %3 to i32
  ret i32 %conv

}

- If the target does not support CTTZ or CTLZ then CTPOP is selected which seems costly. Hence, I tried to revert back to original IR logic by generating similar instructions in expandCTTZ but in between above transformation, the reference to the original table is lost. I tried storing the table reference as a metadata with the intrinsic but it is eventually lost when it reaches expandCTTZ(). I have investigate SPARC backend where I am able to generate -

f:                                      ! @f

  .cfi_startproc

! %bb.0:                                ! %entry

  mov     %o0, %o1
  cmp %o0, 0
  be      .LBB0_2
  mov     %g0, %o0

! %bb.1:                                ! %entry

  sub %o0, %o1, %o0
  and %o1, %o0, %o0
  sethi 122669, %o1
  or %o1, 305, %o1
  smul %o0, %o1, %o0
  srl %o0, 27, %o0

.LBB0_2:                                ! %entry

  retl
  nop

.Lfunc_end0:

  .size   f, .Lfunc_end0-f
  .cfi_endproc
                                  ! -- End function
  .type   f.table, at object                 ! @f.table
  .section        .rodata.cst32,"aM", at progbits,32

f.table:

  .ascii  "\000\001\034\002\035\016\030\003\036\026\024\017\031\021\004\b\037\033\r\027\025\023\020\007\032\f\022\006\013\005\n\t"
  .size   f.table, 32

as compared to original assembly without CTTZ aggressive instcombine optimization -

f:                                      ! @f

  .cfi_startproc

! %bb.0:                                ! %entry

  mov     %g0, %o1
  sub %o1, %o0, %o1
  and %o1, %o0, %o0
  sethi 122669, %o1
  or %o1, 305, %o1
  smul %o0, %o1, %o0
  srl %o0, 27, %o0
  sethi %hi(f.table), %o1
  add %o1, %lo(f.table), %o1
  retl
  ldub [%o1+%o0], %o0

.Lfunc_end0:

  .size   f, .Lfunc_end0-f
  .cfi_endproc
                                  ! -- End function
  .type   f.table, at object                 ! @f.table
  .section        .rodata.cst32,"aM", at progbits,32

f.table:

  .ascii  "\000\001\034\002\035\016\030\003\036\026\024\017\031\021\004\b\037\033\r\027\025\023\020\007\032\f\022\006\013\005\n\t"
  .size   f.table, 32

As you can see that I am missing reference to the table. How should I get reference to the table in expandCTTZ()?

I have this approach in my mind - global dictionary based approach to store the table reference as map<CTTZ, table> in Aggressive InstCombine which we will extract in the expandCTTZ()

and if target does not support CTTZ or CTLZ then in TargetLowering::expandCTTZ(), index into above table. Can you please give your thoughts on more elegant solution?


https://reviews.llvm.org/D128911

Files:
  llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp


Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7835,7 +7835,16 @@
                        DAG.getNode(ISD::CTLZ, dl, VT, Tmp));
   }
 
-  return DAG.getNode(ISD::CTPOP, dl, VT, Tmp);
+  // Emit table lookup by reverting to original IR
+  // table[((unsigned)((x & -x) * 0x077CB531U)) >> 27]
+  SDValue Neg = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT), Op);
+  SDValue Lookup = DAG.getNode(
+      ISD::SRL, dl, VT,
+      DAG.getNode(ISD::MUL, dl, VT, DAG.getNode(ISD::AND, dl, VT, Op, Neg),
+                  DAG.getConstant(0x077CB531U, dl, VT)),
+      DAG.getConstant(27, dl, VT));
+
+  return Lookup;
 }
 
 SDValue TargetLowering::expandABS(SDNode *N, SelectionDAG &DAG,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128911.441383.patch
Type: text/x-patch
Size: 878 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220630/e3c6ed9e/attachment.bin>


More information about the llvm-commits mailing list