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 @@ -4913,7 +4913,9 @@ DAG.getConstant(0, DL, CarryVT)); // (mulo x, 2) -> (addo x, x) - if (N1C && N1C->getAPIntValue() == 2) + // FIXME: This needs a freeze. + if (N1C && N1C->getAPIntValue() == 2 && + (!IsSigned || VT.getScalarSizeInBits() > 2)) return DAG.getNode(IsSigned ? ISD::SADDO : ISD::UADDO, DL, N->getVTList(), N0, N0); diff --git a/llvm/test/CodeGen/AArch64/pr55644.ll b/llvm/test/CodeGen/AArch64/pr55644.ll --- a/llvm/test/CodeGen/AArch64/pr55644.ll +++ b/llvm/test/CodeGen/AArch64/pr55644.ll @@ -5,9 +5,10 @@ ; CHECK-LABEL: f: ; CHECK: ; %bb.0: ; CHECK-NEXT: sbfx w8, w0, #0, #2 -; CHECK-NEXT: add w8, w8, w8 -; CHECK-NEXT: lsl w9, w8, #30 -; CHECK-NEXT: cmp w8, w9, asr #30 +; CHECK-NEXT: lsl w8, w8, #1 +; CHECK-NEXT: neg w9, w8 +; CHECK-NEXT: lsl w9, w9, #30 +; CHECK-NEXT: cmn w8, w9, asr #30 ; CHECK-NEXT: cset w0, ne ; CHECK-NEXT: ret %2 = call { i2, i1 } @llvm.smul.with.overflow.i2(i2 %0, i2 -2)