[InstCombine] Negator: shufflevector is negatible
authorRoman Lebedev <lebedev.ri@gmail.com>
Wed, 22 Apr 2020 11:58:39 +0000 (14:58 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Wed, 22 Apr 2020 12:14:23 +0000 (15:14 +0300)
All these folds are correct as per alive-tv

llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
llvm/test/Transforms/InstCombine/sub-of-negatible.ll

index 32f37c6..e119a38 100644 (file)
@@ -111,6 +111,10 @@ LLVM_NODISCARD Value *Negator::visit(Value *V, unsigned Depth) {
   ++NumValuesVisitedInThisNegator;
 #endif
 
+  // -(undef) -> undef.
+  if (match(V, m_Undef()))
+    return V;
+
   // In i1, negation can simply be ignored.
   if (V->getType()->isIntOrIntVectorTy(1))
     return V;
@@ -265,6 +269,18 @@ LLVM_NODISCARD Value *Negator::visit(Value *V, unsigned Depth) {
     return Builder.CreateSelect(I->getOperand(0), NegOp1, NegOp2,
                                 I->getName() + ".neg", /*MDFrom=*/I);
   }
+  case Instruction::ShuffleVector: {
+    // `shufflevector` is negatible if both operands are negatible.
+    ShuffleVectorInst *Shuf = cast<ShuffleVectorInst>(I);
+    Value *NegOp0 = visit(I->getOperand(0), Depth + 1);
+    if (!NegOp0) // Early return.
+      return nullptr;
+    Value *NegOp1 = visit(I->getOperand(1), Depth + 1);
+    if (!NegOp1)
+      return nullptr;
+    return Builder.CreateShuffleVector(NegOp0, NegOp1, Shuf->getShuffleMask(),
+                                       I->getName() + ".neg");
+  }
   case Instruction::Trunc: {
     // `trunc` is negatible if its operand is negatible.
     Value *NegOp = visit(I->getOperand(0), Depth + 1);
index 21f695f..d676c0b 100644 (file)
@@ -625,9 +625,9 @@ define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) {
 
 define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) {
 ; CHECK-LABEL: @negate_shufflevector_oneinput_reverse(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> undef, <2 x i32> <i32 1, i32 0>
-; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]]
+; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
+; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> undef, <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x i4> [[T2]]
 ;
   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
@@ -637,9 +637,9 @@ define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y)
 }
 define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) {
 ; CHECK-LABEL: @negate_shufflevector_oneinput_second_lane_is_undef(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> undef, <2 x i32> <i32 0, i32 undef>
-; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]]
+; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
+; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> undef, <2 x i32> <i32 0, i32 undef>
+; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x i4> [[T2]]
 ;
   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
@@ -649,10 +649,10 @@ define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x,
 }
 define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
 ; CHECK-LABEL: @negate_shufflevector_twoinputs(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 undef, i4 -1>
-; CHECK-NEXT:    [[T2:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> [[T1]], <2 x i32> <i32 0, i32 3>
-; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[Z:%.*]], [[T2]]
+; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
+; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y:%.*]], <i4 undef, i4 1>
+; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3>
+; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z:%.*]]
 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
 ;
   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x