[PATCH] D32582: [InstCombine] WIP Add range metadata to cttz/ctlz intrinsic calls based on known bits

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 26 23:17:26 PDT 2017


craig.topper created this revision.

I noticed that passing known bits across these intrinsics isn't great at capturing the information we really know. Turning known bits of the input into known bits of a count output isn't able to convey a lot of what we really know.

This patch is a prototype to add range metadata to these intrinsics based on the known bits. I'll add better testing before committing, but I wanted to see if others thought this direction made sense. We can also extend this to ctpop.

Currently the patch punts if we already have range metadata present. Should we analyze the existing metadata and refine it to remove things that aren't possible based on known bits? I think its also possible that later visits of this instruction can get more known bit information if instructions are removed and we are able to look further back the input chain. I didn't see any existing code anywhere that rewrites range metadata like we would need to do here.


https://reviews.llvm.org/D32582

Files:
  lib/Transforms/InstCombine/InstCombineCalls.cpp
  test/Transforms/InstCombine/intrinsics.ll


Index: test/Transforms/InstCombine/intrinsics.ll
===================================================================
--- test/Transforms/InstCombine/intrinsics.ll
+++ test/Transforms/InstCombine/intrinsics.ll
@@ -283,10 +283,7 @@
 
 define i1 @cttz_knownbits(i32 %arg) {
 ; CHECK-LABEL: @cttz_knownbits(
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ARG:%.*]], 4
-; CHECK-NEXT:    [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true) #0
-; CHECK-NEXT:    [[RES:%.*]] = icmp eq i32 [[CNT]], 4
-; CHECK-NEXT:    ret i1 [[RES]]
+; CHECK-NEXT:    ret i1 false
 ;
   %or = or i32 %arg, 4
   %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
@@ -306,10 +303,7 @@
 
 define i1 @ctlz_knownbits(i8 %arg) {
 ; CHECK-LABEL: @ctlz_knownbits(
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[ARG:%.*]], 32
-; CHECK-NEXT:    [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true) #0
-; CHECK-NEXT:    [[RES:%.*]] = icmp eq i8 [[CNT]], 4
-; CHECK-NEXT:    ret i1 [[RES]]
+; CHECK-NEXT:    ret i1 false
 ;
   %or = or i8 %arg, 32
   %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
@@ -405,13 +399,14 @@
 }
 
 define i32 @cttz_make_undef(i32 %a) {
+; CHECK-LABEL: @cttz_make_undef(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], 8
+; CHECK-NEXT:    [[CTTZ:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[OR]], i1 true), !range !1
+; CHECK-NEXT:    ret i32 [[CTTZ]]
+;
   %or = or i32 %a, 8
   %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 false)
   ret i32 %cttz
-; CHECK-LABEL: @cttz_make_undef(
-; CHECK-NEXT: %or = or i32 %a, 8
-; CHECK-NEXT: %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 true)
-; CHECK-NEXT: ret i32 %cttz
 }
 
 define i32 @ctlz_select(i32 %Value) nounwind {
Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1408,7 +1408,15 @@
     }
   }
 
-  return nullptr;
+  if (II.getMetadata(LLVMContext::MD_range))
+    return nullptr;
+
+  Metadata *LowAndHigh[] = {
+      ConstantAsMetadata::get(ConstantInt::get(IT, DefiniteZeros)),
+      ConstantAsMetadata::get(ConstantInt::get(IT, PossibleZeros + 1))};
+  II.setMetadata(LLVMContext::MD_range,
+                 MDNode::get(II.getContext(), LowAndHigh));
+  return ⅈ
 }
 
 // TODO: If the x86 backend knew how to convert a bool vector mask back to an


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32582.96865.patch
Type: text/x-patch
Size: 2416 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170427/4db27d26/attachment.bin>


More information about the llvm-commits mailing list