diff options
-rw-r--r-- | lib/Target/JSBackend/ExpandI64.cpp | 9 | ||||
-rw-r--r-- | test/CodeGen/JS/expand-i64.ll | 15 |
2 files changed, 24 insertions, 0 deletions
diff --git a/lib/Target/JSBackend/ExpandI64.cpp b/lib/Target/JSBackend/ExpandI64.cpp index 1fbf0ddebd..5a5a39ade2 100644 --- a/lib/Target/JSBackend/ExpandI64.cpp +++ b/lib/Target/JSBackend/ExpandI64.cpp @@ -646,6 +646,15 @@ bool ExpandI64::splitInst(Instruction *I) { case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_SGE: { + if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { + if (CI->getZExtValue() == 0 && Pred == ICmpInst::ICMP_SLT) { + // strict < 0 is easy to do, even on non-i64, just the sign bit matters + Instruction *NewInst = new ICmpInst(I, ICmpInst::ICMP_SLT, LeftChunks[LeftChunks.size()-1], Zero); + CopyDebug(NewInst, I); + I->replaceAllUsesWith(NewInst); + return true; + } + } assert(I->getOperand(0)->getType() == i64); Instruction *A, *B, *C, *D, *Final; ICmpInst::Predicate StrictPred = Pred; diff --git a/test/CodeGen/JS/expand-i64.ll b/test/CodeGen/JS/expand-i64.ll index a8a1875fa4..d667548abf 100644 --- a/test/CodeGen/JS/expand-i64.ll +++ b/test/CodeGen/JS/expand-i64.ll @@ -312,3 +312,18 @@ dead: store i64 %s, i64* %p ret void } + +; CHECK: define i1 @slt_zero(i32 %a) { +; CHECK: %1 = icmp slt i32 %a, 0 +; CHECK: %2 = sext i1 %1 to i32 +; CHECK: %3 = sext i1 %1 to i32 +; CHECK: %4 = sext i1 %1 to i32 +; CHECK: %5 = icmp slt i32 %4, 0 +; CHECK: ret i1 %5 +; CHECK: } +define i1 @slt_zero(i32 %a) { + %b = sext i32 %a to i128 + %c = icmp slt i128 %b, 0 + ret i1 %c +} + |