[InstCombine] use constant pattern matchers with icmp+sext
authorSanjay Patel <spatel@rotateright.com>
Thu, 21 Jun 2018 17:51:44 +0000 (17:51 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 21 Jun 2018 17:51:44 +0000 (17:51 +0000)
The previous code worked with vectors, but it failed when the
vector constants contained undef elements.
The matchers handle those cases.

llvm-svn: 335262

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/vec_sext.ll

index aa86ddd..42828ea 100644 (file)
@@ -1191,22 +1191,19 @@ Instruction *InstCombiner::transformSExtICmp(ICmpInst *ICI, Instruction &CI) {
   if (!Op1->getType()->isIntOrIntVectorTy())
     return nullptr;
 
-  if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
+  if ((Pred == ICmpInst::ICMP_SLT && match(Op1, m_ZeroInt())) ||
+      (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes()))) {
     // (x <s  0) ? -1 : 0 -> ashr x, 31        -> all ones if negative
     // (x >s -1) ? -1 : 0 -> not (ashr x, 31)  -> all ones if positive
-    if ((Pred == ICmpInst::ICMP_SLT && Op1C->isNullValue()) ||
-        (Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) {
-
-      Value *Sh = ConstantInt::get(Op0->getType(),
-                                   Op0->getType()->getScalarSizeInBits()-1);
-      Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit");
-      if (In->getType() != CI.getType())
-        In = Builder.CreateIntCast(In, CI.getType(), true /*SExt*/);
-
-      if (Pred == ICmpInst::ICMP_SGT)
-        In = Builder.CreateNot(In, In->getName() + ".not");
-      return replaceInstUsesWith(CI, In);
-    }
+    Value *Sh = ConstantInt::get(Op0->getType(),
+                                 Op0->getType()->getScalarSizeInBits() - 1);
+    Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit");
+    if (In->getType() != CI.getType())
+      In = Builder.CreateIntCast(In, CI.getType(), true /*SExt*/);
+
+    if (Pred == ICmpInst::ICMP_SGT)
+      In = Builder.CreateNot(In, In->getName() + ".not");
+    return replaceInstUsesWith(CI, In);
   }
 
   if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
index f6f0f79..ea76115 100644 (file)
@@ -47,9 +47,8 @@ define <4 x i32> @test1(<4 x i32> %a, <4 x i32> %b) {
 
 define <2 x i32> @is_negative_undef_elt(<2 x i32> %a) {
 ; CHECK-LABEL: @is_negative_undef_elt(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[A:%.*]], <i32 0, i32 undef>
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i32>
-; CHECK-NEXT:    ret <2 x i32> [[SEXT]]
+; CHECK-NEXT:    [[A_LOBIT:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31>
+; CHECK-NEXT:    ret <2 x i32> [[A_LOBIT]]
 ;
   %cmp = icmp slt <2 x i32> %a, <i32 0, i32 undef>
   %sext = sext <2 x i1> %cmp to <2 x i32>
@@ -59,9 +58,9 @@ define <2 x i32> @is_negative_undef_elt(<2 x i32> %a) {
 
 define <2 x i32> @is_positive_undef_elt(<2 x i32> %a) {
 ; CHECK-LABEL: @is_positive_undef_elt(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 undef, i32 -1>
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i32>
-; CHECK-NEXT:    ret <2 x i32> [[SEXT]]
+; CHECK-NEXT:    [[A_LOBIT:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31>
+; CHECK-NEXT:    [[A_LOBIT_NOT:%.*]] = xor <2 x i32> [[A_LOBIT]], <i32 -1, i32 -1>
+; CHECK-NEXT:    ret <2 x i32> [[A_LOBIT_NOT]]
 ;
   %cmp = icmp sgt <2 x i32> %a, <i32 undef, i32 -1>
   %sext = sext <2 x i1> %cmp to <2 x i32>