diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/exact.ll | 16 | 
2 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c2b9e71c6f2..c7ed098cbf8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -919,11 +919,11 @@ Instruction *InstCombiner::FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *Shr,      if (ICI.isSigned() != (Shr->getOpcode() == Instruction::AShr))        return 0; -    // Otherwise, all lshr and all exact ashr's are equivalent to a udiv/sdiv by -    // a power of 2.  Since we already have logic to simplify these, transform -    // to div and then simplify the resultant comparison. +    // Otherwise, all lshr and most exact ashr's are equivalent to a udiv/sdiv +    // by a power of 2.  Since we already have logic to simplify these, +    // transform to div and then simplify the resultant comparison.      if (Shr->getOpcode() == Instruction::AShr && -        !Shr->isExact()) +        (!Shr->isExact() || ShAmtVal == TypeBits - 1))        return 0;      // Revisit the shift (to delete it). diff --git a/llvm/test/Transforms/InstCombine/exact.ll b/llvm/test/Transforms/InstCombine/exact.ll index 58f8b5d5bcd..14741e3c1c3 100644 --- a/llvm/test/Transforms/InstCombine/exact.ll +++ b/llvm/test/Transforms/InstCombine/exact.ll @@ -96,6 +96,22 @@ define i1 @ashr_icmp2(i64 %X) nounwind {   ret i1 %Z  } +; PR9998 +; Make sure we don't transform the ashr here into an sdiv +; CHECK: @pr9998 +; CHECK: = and i32 %V, 1 +; CHECK: %Z = icmp ne +; CHECK: ret i1 %Z +define i1 @pr9998(i32 %V) nounwind { +entry: +  %W = shl i32 %V, 31 +  %X = ashr exact i32 %W, 31 +  %Y = sext i32 %X to i64 +  %Z = icmp ugt i64 %Y, 7297771788697658747 +  ret i1 %Z +} + +  ; CHECK: @udiv_icmp1  ; CHECK: icmp ne i64 %X, 0  define i1 @udiv_icmp1(i64 %X) nounwind {  | 

