diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5738,7 +5738,8 @@ m_CombineOr(m_Specific(CmpLHS), m_SExt(m_Specific(CmpLHS))); auto ZeroOrAllOnes = m_CombineOr(m_ZeroInt(), m_AllOnes()); auto ZeroOrOne = m_CombineOr(m_ZeroInt(), m_One()); - if (match(TrueVal, MaybeSExtCmpLHS)) { + if (match(TrueVal, MaybeSExtCmpLHS) || + match(CmpLHS, m_SExt(m_Specific(TrueVal)))) { // Set the return values. If the compare uses the negated value (-X >s 0), // swap the return values because the negated value is always 'RHS'. LHS = TrueVal; @@ -5759,8 +5760,8 @@ // (-X NABS(X) if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, ZeroOrOne)) return {SPF_NABS, SPNB_NA, false}; - } - else if (match(FalseVal, MaybeSExtCmpLHS)) { + } else if (match(FalseVal, MaybeSExtCmpLHS) || + match(CmpLHS, m_SExt(m_Specific(FalseVal)))) { // Set the return values. If the compare uses the negated value (-X >s 0), // swap the return values because the negated value is always 'RHS'. LHS = FalseVal; diff --git a/llvm/test/CodeGen/NVPTX/idioms.ll b/llvm/test/CodeGen/NVPTX/idioms.ll --- a/llvm/test/CodeGen/NVPTX/idioms.ll +++ b/llvm/test/CodeGen/NVPTX/idioms.ll @@ -12,6 +12,16 @@ ret i16 %abs } +; CHECK-LABEL: abs_extcmp_i16( +define i16 @abs_extcmp_i16(i16 %a) { +; CHECK: abs.s16 + %neg = sub i16 0, %a + %a.prom = sext i16 %a to i32 + %abs.cond = icmp sge i32 %a.prom, 0 + %abs = select i1 %abs.cond, i16 %a, i16 %neg + ret i16 %abs +} + ; CHECK-LABEL: abs_i32( define i32 @abs_i32(i32 %a) { ; CHECK: abs.s32