OSDN Git Service

[InstCombine] Add support for simplifying ctlz/cttz intrinsics based on known bits.
authorCraig Topper <craig.topper@gmail.com>
Sat, 3 Jun 2017 18:50:32 +0000 (18:50 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sat, 3 Jun 2017 18:50:32 +0000 (18:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304669 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b44499e..644dfd5 100644 (file)
@@ -1373,10 +1373,6 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
           II.getIntrinsicID() == Intrinsic::ctlz) &&
          "Expected cttz or ctlz intrinsic");
   Value *Op0 = II.getArgOperand(0);
-  // FIXME: Try to simplify vectors of integers.
-  auto *IT = dyn_cast<IntegerType>(Op0->getType());
-  if (!IT)
-    return nullptr;
 
   KnownBits Known = IC.computeKnownBits(Op0, 0, &II);
 
@@ -1392,7 +1388,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
   // FIXME: This should be in InstSimplify because we're replacing an
   // instruction with a constant.
   if (PossibleZeros == DefiniteZeros) {
-    auto *C = ConstantInt::get(IT, DefiniteZeros);
+    auto *C = ConstantInt::get(Op0->getType(), DefiniteZeros);
     return IC.replaceInstUsesWith(II, C);
   }
 
index abe0c78..1b1ed60 100644 (file)
@@ -285,10 +285,7 @@ define i32 @cttz(i32 %a) {
 
 define <2 x i32> @cttz_vec(<2 x i32> %a) {
 ; CHECK-LABEL: @cttz_vec(
-; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[OR]], <i32 -8, i32 -8>
-; CHECK-NEXT:    [[COUNT:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[AND]], i1 true)
-; CHECK-NEXT:    ret <2 x i32> [[COUNT]]
+; CHECK-NEXT:    ret <2 x i32> <i32 3, i32 3>
 ;
   %or = or <2 x i32> %a, <i32 8, i32 8>
   %and = and <2 x i32> %or, <i32 -8, i32 -8>
@@ -382,10 +379,7 @@ define i8 @ctlz(i8 %a) {
 
 define <2 x i8> @ctlz_vec(<2 x i8> %a) {
 ; CHECK-LABEL: @ctlz_vec(
-; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[A:%.*]], <i8 32, i8 32>
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[OR]], <i8 63, i8 63>
-; CHECK-NEXT:    [[COUNT:%.*]] = tail call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> [[AND]], i1 true)
-; CHECK-NEXT:    ret <2 x i8> [[COUNT]]
+; CHECK-NEXT:    ret <2 x i8> <i8 2, i8 2>
 ;
   %or = or <2 x i8> %a, <i8 32, i8 32>
   %and = and <2 x i8> %or, <i8 63, i8 63>
@@ -556,7 +550,7 @@ define i32 @ctlz_make_undef(i32 %a) {
 define <2 x i32> @ctlz_make_undef_vec(<2 x i32> %a) {
 ; CHECK-LABEL: @ctlz_make_undef_vec(
 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
-; CHECK-NEXT:    [[CTLZ:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[OR]], i1 false)
+; CHECK-NEXT:    [[CTLZ:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[OR]], i1 true)
 ; CHECK-NEXT:    ret <2 x i32> [[CTLZ]]
 ;
   %or = or <2 x i32> %a, <i32 8, i32 8>
@@ -593,7 +587,7 @@ define i32 @cttz_make_undef(i32 %a) {
 define <2 x i32> @cttz_make_undef_vec(<2 x i32> %a) {
 ; CHECK-LABEL: @cttz_make_undef_vec(
 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
-; CHECK-NEXT:    [[CTTZ:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 false)
+; CHECK-NEXT:    [[CTTZ:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
 ; CHECK-NEXT:    ret <2 x i32> [[CTTZ]]
 ;
   %or = or <2 x i32> %a, <i32 8, i32 8>