diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index d9ccd86802c7..cfb77f466cd1 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -5062,7 +5062,7 @@ static bool isSaturatingConditional(const SDValue &Op, SDValue &V, int64_t PosVal = std::max(Val1, Val2); int64_t NegVal = std::min(Val1, Val2); - if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) && + if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) || !isPowerOf2_64(PosVal + 1)) return false; diff --git a/llvm/test/CodeGen/ARM/usat.ll b/llvm/test/CodeGen/ARM/usat.ll index 99064386fa50..ba4e0dd03764 100644 --- a/llvm/test/CodeGen/ARM/usat.ll +++ b/llvm/test/CodeGen/ARM/usat.ll @@ -176,6 +176,18 @@ entry: ret i32 %saturateUp } +; The interval is [0, k] but k+1 is not a power of 2 +define i32 @no_unsigned_sat_incorrect_constant2(i32 %x) #0 { +; CHECK-LABEL: no_unsigned_sat_incorrect_constant2: +; CHECK-NOT: usat +entry: + %0 = icmp sgt i32 %x, 0 + %saturateLow = select i1 %0, i32 %x, i32 0 + %1 = icmp slt i32 %saturateLow, 8388609 + %saturateUp = select i1 %1, i32 %saturateLow, i32 8388609 + ret i32 %saturateUp +} + ; The interval is not [0, k] define i32 @no_unsigned_sat_incorrect_interval(i32 %x) #0 { ; CHECK-LABEL: no_unsigned_sat_incorrect_interval: