diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5207,6 +5207,11 @@ if (N0.isUndef() || N1.isUndef()) return DAG.getConstant(0, DL, VT); + // fold (abds x, y) -> (abdu x, y) iff both args are known positive + if (Opcode == ISD::ABDS && hasOperation(ISD::ABDU, VT) && + DAG.SignBitIsZero(N0) && DAG.SignBitIsZero(N1)) + return DAG.getNode(ISD::ABDU, DL, VT, N1, N0); + return SDValue(); } diff --git a/llvm/test/CodeGen/PowerPC/vec-zext-abdu.ll b/llvm/test/CodeGen/PowerPC/vec-zext-abdu.ll --- a/llvm/test/CodeGen/PowerPC/vec-zext-abdu.ll +++ b/llvm/test/CodeGen/PowerPC/vec-zext-abdu.ll @@ -20,17 +20,11 @@ ; CHECK-NEXT: vperm 1, 4, 3, 1 ; CHECK-NEXT: vperm 2, 4, 2, 7 ; CHECK-NEXT: vperm 3, 4, 3, 7 -; CHECK-NEXT: xvnegsp 36, 38 -; CHECK-NEXT: xvnegsp 35, 35 -; CHECK-NEXT: xvnegsp 34, 34 -; CHECK-NEXT: vabsduw 2, 2, 3 -; CHECK-NEXT: xvnegsp 35, 33 -; CHECK-NEXT: vabsduw 3, 4, 3 -; CHECK-NEXT: xvnegsp 36, 37 -; CHECK-NEXT: xvnegsp 37, 32 -; CHECK-NEXT: vpkuwum 2, 2, 2 -; CHECK-NEXT: vabsduw 4, 5, 4 +; CHECK-NEXT: vabsduw 4, 5, 0 +; CHECK-NEXT: vabsduw 2, 3, 2 +; CHECK-NEXT: vabsduw 3, 1, 6 ; CHECK-NEXT: vpkuwum 3, 4, 3 +; CHECK-NEXT: vpkuwum 2, 2, 2 ; CHECK-NEXT: vpkuhum 2, 2, 3 ; CHECK-NEXT: blr entry: