Index: llvm/lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -3443,32 +3443,42 @@ SDValue Carry = Op.getOperand(2); SDLoc DL(N); unsigned BaseOp = 0; - unsigned CCValid = 0; - unsigned CCMask = 0; + unsigned CCValid = SystemZ::CCMASK_LOGICAL; + unsigned CCMaskIn = 0; + unsigned CCMaskOut = 0; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::ADDCARRY: BaseOp = SystemZISD::ADDCARRY; - CCValid = SystemZ::CCMASK_LOGICAL; - CCMask = SystemZ::CCMASK_LOGICAL_CARRY; + CCMaskOut = SystemZ::CCMASK_LOGICAL_CARRY; break; case ISD::SUBCARRY: BaseOp = SystemZISD::SUBCARRY; - CCValid = SystemZ::CCMASK_LOGICAL; - CCMask = SystemZ::CCMASK_LOGICAL_BORROW; + CCMaskOut = SystemZ::CCMASK_LOGICAL_BORROW; + break; + } + switch (Carry.getOpcode()) { + default: + // Unknown source, let legalization deal with it. + return SDValue(); + case ISD::UADDO: + CCMaskIn = SystemZ::CCMASK_LOGICAL_CARRY; + break; + case ISD::USUBO: + CCMaskIn = SystemZ::CCMASK_LOGICAL_BORROW; break; } // Set the condition code from the carry flag. Carry = DAG.getNode(SystemZISD::GET_CCMASK, DL, MVT::i32, Carry, DAG.getConstant(CCValid, DL, MVT::i32), - DAG.getConstant(CCMask, DL, MVT::i32)); + DAG.getConstant(CCMaskIn, DL, MVT::i32)); SDVTList VTs = DAG.getVTList(VT, MVT::i32); SDValue Result = DAG.getNode(BaseOp, DL, VTs, LHS, RHS, Carry); - SDValue SetCC = emitSETCC(DAG, DL, Result.getValue(1), CCValid, CCMask); + SDValue SetCC = emitSETCC(DAG, DL, Result.getValue(1), CCValid, CCMaskOut); if (N->getValueType(1) == MVT::i1) SetCC = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC); Index: llvm/test/CodeGen/SystemZ/pr42512.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/pr42512.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +define i8 @test(i8 %x) { +; CHECK-LABEL: test: +; CHECK: # %bb.0: +; CHECK-NEXT: slgfi %r0, 1 +; CHECK-NEXT: lhi %r0, 0 +; CHECK-NEXT: alcr %r2, %r0 +; CHECK-NEXT: br %r14 + %usubo = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 undef, i64 1) + %ov = extractvalue { i64, i1 } %usubo, 1 + %ovext = zext i1 %ov to i8 + %ret = add i8 %x, %ovext + ret i8 %ret +} + +; Function Attrs: nounwind readnone speculatable +declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) #0 + +attributes #0 = { nounwind readnone speculatable }