Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2469,6 +2469,20 @@ } } + // sext(X + Y) - sext(X + Z) -> sext(Y) - sext(Z) + if (match(Op0, m_SExt(m_NSWAdd(m_Value(X), m_Value(Y)))) && + match(Op1, m_SExt(m_NSWAdd(m_Specific(X), m_Value(Z))))) { + Value *S1 = Builder.CreateSExt(Y, Ty); + Value *S2 = Builder.CreateSExt(Z, Ty); + return BinaryOperator::CreateSub(S1, S2); + } + if (match(Op0, m_ZExt(m_NUWAdd(m_Value(X), m_Value(Y)))) && + match(Op1, m_ZExt(m_NUWAdd(m_Specific(X), m_Value(Z))))) { + Value *S1 = Builder.CreateZExt(Y, Ty); + Value *S2 = Builder.CreateZExt(Z, Ty); + return BinaryOperator::CreateSub(S1, S2); + } + if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I)) return Res; Index: llvm/test/Transforms/InstCombine/sub-ext-add.ll =================================================================== --- llvm/test/Transforms/InstCombine/sub-ext-add.ll +++ llvm/test/Transforms/InstCombine/sub-ext-add.ll @@ -5,11 +5,9 @@ define i32 @subaddnuw(i8 %a, i8 %C1, i8 %C2) { ; CHECK-LABEL: @subaddnuw( -; CHECK-NEXT: [[L3619:%.*]] = add nuw i8 [[A:%.*]], [[C1:%.*]] -; CHECK-NEXT: [[L3620:%.*]] = zext i8 [[L3619]] to i32 -; CHECK-NEXT: [[L3621:%.*]] = add nuw i8 [[A]], [[C2:%.*]] -; CHECK-NEXT: [[L3622:%.*]] = zext i8 [[L3621]] to i32 -; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]] +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[C2:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[C1:%.*]] to i32 +; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret i32 [[L3623]] ; %l3619 = add nuw i8 %a, %C1 @@ -22,12 +20,7 @@ define i32 @subaddnuw_c(i8 %a) { ; CHECK-LABEL: @subaddnuw_c( -; CHECK-NEXT: [[L3619:%.*]] = add nuw i8 [[A:%.*]], 1 -; CHECK-NEXT: [[L3620:%.*]] = zext i8 [[L3619]] to i32 -; CHECK-NEXT: [[L3621:%.*]] = add nuw i8 [[A]], 2 -; CHECK-NEXT: [[L3622:%.*]] = zext i8 [[L3621]] to i32 -; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]] -; CHECK-NEXT: ret i32 [[L3623]] +; CHECK-NEXT: ret i32 1 ; %l3619 = add nuw i8 %a, 1 %l3620 = zext i8 %l3619 to i32 @@ -39,11 +32,9 @@ define i32 @subaddnsw(i8 %a, i8 %C1, i8 %C2) { ; CHECK-LABEL: @subaddnsw( -; CHECK-NEXT: [[L3619:%.*]] = add nsw i8 [[A:%.*]], [[C1:%.*]] -; CHECK-NEXT: [[L3620:%.*]] = sext i8 [[L3619]] to i32 -; CHECK-NEXT: [[L3621:%.*]] = add nsw i8 [[A]], [[C2:%.*]] -; CHECK-NEXT: [[L3622:%.*]] = sext i8 [[L3621]] to i32 -; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]] +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[C2:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = sext i8 [[C1:%.*]] to i32 +; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret i32 [[L3623]] ; %l3619 = add nsw i8 %a, %C1 @@ -56,12 +47,7 @@ define i32 @subaddnsw_c(i8 %a) { ; CHECK-LABEL: @subaddnsw_c( -; CHECK-NEXT: [[L3619:%.*]] = add nsw i8 [[A:%.*]], 1 -; CHECK-NEXT: [[L3620:%.*]] = sext i8 [[L3619]] to i32 -; CHECK-NEXT: [[L3621:%.*]] = add nsw i8 [[A]], 2 -; CHECK-NEXT: [[L3622:%.*]] = sext i8 [[L3621]] to i32 -; CHECK-NEXT: [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]] -; CHECK-NEXT: ret i32 [[L3623]] +; CHECK-NEXT: ret i32 1 ; %l3619 = add nsw i8 %a, 1 %l3620 = sext i8 %l3619 to i32