aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/NaCl/PromoteIntegers.cpp30
-rw-r--r--test/Transforms/NaCl/promote-integers.ll56
2 files changed, 81 insertions, 5 deletions
diff --git a/lib/Transforms/NaCl/PromoteIntegers.cpp b/lib/Transforms/NaCl/PromoteIntegers.cpp
index af34faa7e5..ed374da3dd 100644
--- a/lib/Transforms/NaCl/PromoteIntegers.cpp
+++ b/lib/Transforms/NaCl/PromoteIntegers.cpp
@@ -577,18 +577,38 @@ void PromoteIntegers::convertInstruction(Instruction *Inst, ConversionState &Sta
State.getConverted(Binop->getOperand(1)),
Binop->getName() + ".result", Binop), Binop);
break;
+ // XXX EMSCRIPTEN: Implement {U,S}{Div,Rem}
+ case Instruction::UDiv:
+ case Instruction::URem:
+ NewInst = CopyDebug(BinaryOperator::Create(
+ Binop->getOpcode(),
+ getClearConverted(Binop->getOperand(0),
+ Binop,
+ State),
+ getClearConverted(Binop->getOperand(1),
+ Binop,
+ State),
+ Binop->getName() + ".result", Binop), Binop);
+ break;
+ case Instruction::SDiv:
+ case Instruction::SRem:
+ NewInst = CopyDebug(BinaryOperator::Create(
+ Binop->getOpcode(),
+ getSignExtend(State.getConverted(Binop->getOperand(0)),
+ Binop->getOperand(0),
+ Binop),
+ getSignExtend(State.getConverted(Binop->getOperand(1)),
+ Binop->getOperand(0),
+ Binop),
+ Binop->getName() + ".result", Binop), Binop);
+ break;
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
- case Instruction::UDiv:
- case Instruction::SDiv:
case Instruction::FDiv:
- case Instruction::URem:
- case Instruction::SRem:
case Instruction::FRem:
case Instruction::BinaryOpsEnd:
// We should not see FP operators here.
- // We don't handle div.
errs() << *Inst << "\n";
llvm_unreachable("Cannot handle binary operator");
break;
diff --git a/test/Transforms/NaCl/promote-integers.ll b/test/Transforms/NaCl/promote-integers.ll
index 7c010be32b..baab0822cd 100644
--- a/test/Transforms/NaCl/promote-integers.ll
+++ b/test/Transforms/NaCl/promote-integers.ll
@@ -228,6 +228,62 @@ define void @ashr1(i16 %a) {
ret void
}
+; CHECK: @udiv1
+define void @udiv1(i32 %a, i32 %b) {
+; CHECK-NEXT: %a33 = zext i32 %a to i64
+ %a33 = zext i32 %a to i33
+; CHECK-NEXT: %b33 = zext i32 %b to i64
+ %b33 = zext i32 %b to i33
+; CHECK-NEXT: %a33.clear = and i64 %a33, 8589934591
+; CHECK-NEXT: %b33.clear = and i64 %b33, 8589934591
+; CHECK-NEXT: %result = udiv i64 %a33.clear, %b33.clear
+ %result = udiv i33 %a33, %b33
+ ret void
+}
+
+; CHECK: @sdiv1
+define void @sdiv1(i32 %a, i32 %b) {
+; CHECK-NEXT: %a33 = sext i32 %a to i64
+ %a33 = sext i32 %a to i33
+; CHECK-NEXT: %b33 = sext i32 %b to i64
+; CHECK-NEXT: %a33.getsign = shl i64 %a33, 31
+; CHECK-NEXT: %a33.signed = ashr i64 %a33.getsign, 31
+; CHECK-NEXT: %b33.getsign = shl i64 %b33, 31
+; CHECK-NEXT: %b33.signed = ashr i64 %b33.getsign, 31
+ %b33 = sext i32 %b to i33
+; CHECK-NEXT: %result = sdiv i64 %a33.signed, %b33.signed
+ %result = sdiv i33 %a33, %b33
+ ret void
+}
+
+; CHECK: @urem1
+define void @urem1(i32 %a, i32 %b) {
+; CHECK-NEXT: %a33 = zext i32 %a to i64
+ %a33 = zext i32 %a to i33
+; CHECK-NEXT: %b33 = zext i32 %b to i64
+; CHECK-NEXT: %a33.clear = and i64 %a33, 8589934591
+; CHECK-NEXT: %b33.clear = and i64 %b33, 8589934591
+ %b33 = zext i32 %b to i33
+; CHECK-NEXT: %result = urem i64 %a33.clear, %b33.clear
+ %result = urem i33 %a33, %b33
+ ret void
+}
+
+; CHECK: @srem1
+define void @srem1(i32 %a, i32 %b) {
+; CHECK-NEXT: %a33 = sext i32 %a to i64
+ %a33 = sext i32 %a to i33
+; CHECK-NEXT: %b33 = sext i32 %b to i64
+; CHECK-NEXT: %a33.getsign = shl i64 %a33, 31
+; CHECK-NEXT: %a33.signed = ashr i64 %a33.getsign, 31
+; CHECK-NEXT: %b33.getsign = shl i64 %b33, 31
+; CHECK-NEXT: %b33.signed = ashr i64 %b33.getsign, 31
+ %b33 = sext i32 %b to i33
+; CHECK-NEXT: %result = srem i64 %a33.signed, %b33.signed
+ %result = srem i33 %a33, %b33
+ ret void
+}
+
; CHECK: @phi_icmp
define void @phi_icmp(i32 %a) {
entry: