++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;
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);
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
}
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
}
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