[llvm] 4c38c35 - [ValueTracking] Teach canCreateUndefOrPoison that ctpop does not create undef or poison.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 23 12:47:39 PDT 2021


Author: Craig Topper
Date: 2021-03-23T12:42:18-07:00
New Revision: 4c38c35c8d846a3ca1409f17eea776d15bcbcd4e

URL: https://github.com/llvm/llvm-project/commit/4c38c35c8d846a3ca1409f17eea776d15bcbcd4e
DIFF: https://github.com/llvm/llvm-project/commit/4c38c35c8d846a3ca1409f17eea776d15bcbcd4e.diff

LOG: [ValueTracking] Teach canCreateUndefOrPoison that ctpop does not create undef or poison.

This select of ctpop with 0 pattern can get left behind after
loop idiom recognize converts a loop to ctpop. LLVM 10 was able
to optimize this, but LLVM 11 and later is not. The difference
seems to be that some select transforms are now limited based
on canCreateUndefOrPoison.

Teaching canCreateUndefOrPoison about ctpop restores the
LLVM 10 codegen.

Differential Revision: https://reviews.llvm.org/D99207

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstSimplify/select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b2f105f13ba3..c0f41c7caa3e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4794,6 +4794,14 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly) {
     // destination type.
     return true;
   case Instruction::Call:
+    if (auto *II = dyn_cast<IntrinsicInst>(Op)) {
+      switch (II->getIntrinsicID()) {
+      // TODO: Add more intrinsics.
+      case Intrinsic::ctpop:
+        return false;
+      }
+    }
+    LLVM_FALLTHROUGH;
   case Instruction::CallBr:
   case Instruction::Invoke: {
     const auto *CB = cast<CallBase>(Op);

diff  --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll
index 86d76725e131..f106b909a8ac 100644
--- a/llvm/test/Transforms/InstSimplify/select.ll
+++ b/llvm/test/Transforms/InstSimplify/select.ll
@@ -1015,6 +1015,20 @@ define i32 @select_neutral_sub_lhs(i32 %x, i32 %y) {
   ret i32 %sel
 }
 
+define i32 @select_ctpop_zero(i32 %x) {
+; CHECK-LABEL: @select_ctpop_zero(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP0]]
+;
+entry:
+  %0 = icmp eq i32 %x, 0
+  %1 = call i32 @llvm.ctpop.i32(i32 %x)
+  %sel = select i1 %0, i32 0, i32 %1
+  ret i32 %sel
+}
+declare i32 @llvm.ctpop.i32(i32)
+
 ; TODO: these can be optimized more
 
 define i32 @poison(i32 %x, i32 %y) {


        


More information about the llvm-commits mailing list