[llvm-commits] [dragonegg] r94966 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Sun Jan 31 12:45:06 PST 2010
Author: baldrick
Date: Sun Jan 31 14:45:05 2010
New Revision: 94966
URL: http://llvm.org/viewvc/llvm-project?rev=94966&view=rev
Log:
Handle TRUNC_DIV_EXPR and EXACT_DIV_EXPR directly, rather than going via
EmitReg_BinOp. Implement complex integer division while there (amusingly,
llvm-gcc will crash if you try to divide two complex integers...).
Modified:
dragonegg/trunk/llvm-convert.cpp
dragonegg/trunk/llvm-internal.h
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=94966&r1=94965&r2=94966&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Sun Jan 31 14:45:05 2010
@@ -6035,7 +6035,6 @@
bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(op0));
bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(op1));
bool TyIsSigned = !TYPE_UNSIGNED(type);
- bool IsExactDiv = code == EXACT_DIV_EXPR;
const Type *Ty = GetRegType(type);
LHS = CastToAnyType(LHS, LHSIsSigned, Ty, TyIsSigned);
@@ -6055,11 +6054,7 @@
RHS = UselesslyTypeConvert(RHS, Ty);
}
- Value *V;
- if (Opc == Instruction::SDiv && IsExactDiv)
- V = Builder.CreateExactSDiv(LHS, RHS);
- else
- V = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS);
+ Value *V = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS);
return UselesslyTypeConvert(V, ResTy);
}
@@ -6540,6 +6535,53 @@
"rdiv");
}
+Value *TreeToLLVM::EmitReg_TRUNC_DIV_EXPR(tree op0, tree op1, bool isExact) {
+ Value *LHS = EmitRegister(op0);
+ Value *RHS = EmitRegister(op1);
+ tree type = TREE_TYPE(op0);
+
+ if (TREE_CODE(type) == COMPLEX_TYPE) {
+ tree elt_type = TREE_TYPE(type);
+ Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
+ Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+ Value *DSTr, *DSTi;
+
+ // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
+ assert (LHSr->getType()->isInteger() &&
+ "TRUNC_DIV_EXPR not integer!");
+ Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
+ Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
+ Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd
+
+ Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c
+ Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d
+ Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd
+ DSTr = TYPE_UNSIGNED(elt_type) ?
+ Builder.CreateUDiv(Tmp3, Tmp6) : Builder.CreateSDiv(Tmp3, Tmp6);
+
+ Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c
+ Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d
+ Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad
+ DSTi = TYPE_UNSIGNED(elt_type) ?
+ Builder.CreateUDiv(Tmp9, Tmp6) : Builder.CreateSDiv(Tmp9, Tmp6);
+
+ return CreateComplex(DSTr, DSTi, elt_type);
+ }
+
+ assert(LHS->getType()->isIntOrIntVector() && "TRUNC_DIV_EXPR not integer!");
+ if (TYPE_UNSIGNED(type)) {
+// if (isExact)
+// return Builder.CreateExactUDiv(LHS, RHS);
+// else
+ return Builder.CreateUDiv(LHS, RHS);
+ } else {
+ if (isExact)
+ return Builder.CreateExactSDiv(LHS, RHS);
+ else
+ return Builder.CreateSDiv(LHS, RHS);
+ }
+}
+
//===----------------------------------------------------------------------===//
// ... Exception Handling ...
@@ -7251,9 +7293,7 @@
case COMPLEX_EXPR:
RHS = EmitReg_COMPLEX_EXPR(rhs1, rhs2); break;
case EXACT_DIV_EXPR:
- RHS = EmitReg_BinOp(type, code, rhs1, rhs2, TYPE_UNSIGNED(type) ?
- Instruction::UDiv : Instruction::SDiv);
- break;
+ RHS = EmitReg_TRUNC_DIV_EXPR(rhs1, rhs2, /*isExact*/true); break;
case FLOOR_DIV_EXPR:
RHS = EmitReg_FLOOR_DIV_EXPR(type, rhs1, rhs2); break;
case FLOOR_MOD_EXPR:
@@ -7293,9 +7333,7 @@
Instruction::LShr : Instruction::AShr);
break;
case TRUNC_DIV_EXPR:
- RHS = EmitReg_BinOp(type, code, rhs1, rhs2, TYPE_UNSIGNED(type) ?
- Instruction::UDiv : Instruction::SDiv);
- break;
+ RHS = EmitReg_TRUNC_DIV_EXPR(rhs1, rhs2, /*isExact*/false); break;
case TRUNC_MOD_EXPR:
RHS = EmitReg_BinOp(type, code, rhs1, rhs2, TYPE_UNSIGNED(type) ?
Instruction::URem : Instruction::SRem);
Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=94966&r1=94965&r2=94966&view=diff
==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Sun Jan 31 14:45:05 2010
@@ -652,6 +652,7 @@
Value *EmitReg_RDIV_EXPR(tree_node *op0, tree_node *op1);
Value *EmitReg_ROUND_DIV_EXPR(tree_node *type, tree_node *op0,
tree_node *op1);
+ Value *EmitReg_TRUNC_DIV_EXPR(tree_node *op0, tree_node *op1, bool isExact);
Value *EmitLoadOfLValue(tree_node *exp);
More information about the llvm-commits
mailing list