Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -548,7 +548,7 @@ SDValue N0, SDValue N1); SDValue reassociateOpsCommutative(unsigned Opc, const SDLoc &DL, SDValue N0, - SDValue N1); + SDValue N1, SDNodeFlags Flags); SDValue reassociateOps(unsigned Opc, const SDLoc &DL, SDValue N0, SDValue N1, SDNodeFlags Flags); SDValue reassociateReduction(unsigned ResOpc, unsigned Opc, const SDLoc &DL, @@ -1251,7 +1251,8 @@ // Helper for DAGCombiner::reassociateOps. Try to reassociate an expression // such as (Opc N0, N1), if \p N0 is the same kind of operation as \p Opc. SDValue DAGCombiner::reassociateOpsCommutative(unsigned Opc, const SDLoc &DL, - SDValue N0, SDValue N1) { + SDValue N0, SDValue N1, + SDNodeFlags Flags) { EVT VT = N0.getValueType(); if (N0.getOpcode() != Opc) @@ -1270,8 +1271,12 @@ if (TLI.isReassocProfitable(DAG, N0, N1)) { // Reassociate: (op (op x, c1), y) -> (op (op x, y), c1) // iff (op x, c1) has one use - SDValue OpNode = DAG.getNode(Opc, SDLoc(N0), VT, N00, N1); - return DAG.getNode(Opc, DL, VT, OpNode, N01); + SDNodeFlags NewFlags; + if (N0.getOpcode() == ISD::ADD && N0->getFlags().hasNoUnsignedWrap() && + Flags.hasNoUnsignedWrap()) + NewFlags.setNoUnsignedWrap(true); + SDValue OpNode = DAG.getNode(Opc, SDLoc(N0), VT, N00, N1, NewFlags); + return DAG.getNode(Opc, DL, VT, OpNode, N01, NewFlags); } } @@ -1329,9 +1334,9 @@ if (!Flags.hasAllowReassociation() || !Flags.hasNoSignedZeros()) return SDValue(); - if (SDValue Combined = reassociateOpsCommutative(Opc, DL, N0, N1)) + if (SDValue Combined = reassociateOpsCommutative(Opc, DL, N0, N1, Flags)) return Combined; - if (SDValue Combined = reassociateOpsCommutative(Opc, DL, N1, N0)) + if (SDValue Combined = reassociateOpsCommutative(Opc, DL, N1, N0, Flags)) return Combined; return SDValue(); } Index: llvm/test/CodeGen/Thumb2/mve-vhadd.ll =================================================================== --- llvm/test/CodeGen/Thumb2/mve-vhadd.ll +++ llvm/test/CodeGen/Thumb2/mve-vhadd.ll @@ -312,12 +312,9 @@ ; CHECK-LABEL: vrhaddu_v4i8: ; CHECK: @ %bb.0: @ %entry ; CHECK-NEXT: vmov.i32 q2, #0xff -; CHECK-NEXT: movs r0, #1 ; CHECK-NEXT: vand q1, q1, q2 ; CHECK-NEXT: vand q0, q0, q2 -; CHECK-NEXT: vadd.i32 q0, q0, q1 -; CHECK-NEXT: vadd.i32 q0, q0, r0 -; CHECK-NEXT: vshr.u32 q0, q0, #1 +; CHECK-NEXT: vrhadd.u32 q0, q0, q1 ; CHECK-NEXT: bx lr entry: %s0s = zext <4 x i8> %s0 to <4 x i16>