[llvm-commits] [dragonegg] r94961 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Sun Jan 31 08:12:49 PST 2010
Author: baldrick
Date: Sun Jan 31 10:12:49 2010
New Revision: 94961
URL: http://llvm.org/viewvc/llvm-project?rev=94961&view=rev
Log:
Move MULT_EXPR out of EmitReg_BinOp and EmitComplexBinOp: handle it
directly.
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=94961&r1=94960&r2=94961&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Sun Jan 31 10:12:49 2010
@@ -5057,26 +5057,6 @@
Value *DSTr, *DSTi;
switch (code) {
default: llvm_unreachable("Unhandled complex binop!");
- case MULT_EXPR: { // (a+ib) * (c+id) = (ac-bd) + i(ad+cb)
- if (LHSr->getType()->isFloatingPoint()) {
- Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c
- Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d
- DSTr = Builder.CreateFSub(Tmp1, Tmp2); // ac-bd
-
- Value *Tmp3 = Builder.CreateFMul(LHSr, RHSi); // a*d
- Value *Tmp4 = Builder.CreateFMul(RHSr, LHSi); // c*b
- DSTi = Builder.CreateFAdd(Tmp3, Tmp4); // ad+cb
- } else {
- Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
- Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
- DSTr = Builder.CreateSub(Tmp1, Tmp2); // ac-bd
-
- Value *Tmp3 = Builder.CreateMul(LHSr, RHSi); // a*d
- Value *Tmp4 = Builder.CreateMul(RHSr, LHSi); // c*b
- DSTi = Builder.CreateAdd(Tmp3, Tmp4); // ad+cb
- }
- break;
- }
case RDIV_EXPR: { // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
// RDIV_EXPR should always be floating point.
assert (LHSr->getType()->isFloatingPoint());
@@ -6113,8 +6093,6 @@
Value *V;
if (Opc == Instruction::SDiv && IsExactDiv)
V = Builder.CreateExactSDiv(LHS, RHS);
- else if (Opc == Instruction::Mul && !TYPE_OVERFLOW_WRAPS(type))
- V = Builder.CreateNSWMul(LHS, RHS);
else
V = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS);
@@ -6386,6 +6364,51 @@
return Builder.CreateNSWSub(LHS, RHS);
}
+Value *TreeToLLVM::EmitReg_MULT_EXPR(tree op0, tree op1) {
+ 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) + i(ad+cb)
+ if (LHSr->getType()->isFloatingPoint()) {
+ Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c
+ Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d
+ DSTr = Builder.CreateFSub(Tmp1, Tmp2); // ac-bd
+
+ Value *Tmp3 = Builder.CreateFMul(LHSr, RHSi); // a*d
+ Value *Tmp4 = Builder.CreateFMul(RHSr, LHSi); // c*b
+ DSTi = Builder.CreateFAdd(Tmp3, Tmp4); // ad+cb
+ } else {
+ // If overflow does not wrap in the element type then it is tempting to
+ // use NSW operations here. However that would be wrong since overflow
+ // of an intermediate value calculated here does not necessarily imply
+ // that the final result overflows.
+ Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
+ Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
+ DSTr = Builder.CreateSub(Tmp1, Tmp2); // ac-bd
+
+ Value *Tmp3 = Builder.CreateMul(LHSr, RHSi); // a*d
+ Value *Tmp4 = Builder.CreateMul(RHSr, LHSi); // c*b
+ DSTi = Builder.CreateAdd(Tmp3, Tmp4); // ad+cb
+ }
+
+ return CreateComplex(DSTr, DSTi, elt_type);
+ }
+
+ if (LHS->getType()->isFPOrFPVector())
+ return Builder.CreateFMul(LHS, RHS);
+ else if (TYPE_OVERFLOW_WRAPS(type))
+ return Builder.CreateMul(LHS, RHS);
+ else
+ return Builder.CreateNSWMul(LHS, RHS);
+}
+
Value *TreeToLLVM::EmitReg_PLUS_EXPR(tree op0, tree op1) {
Value *LHS = EmitRegister(op0);
Value *RHS = EmitRegister(op1);
@@ -7253,8 +7276,7 @@
RHS = EmitReg_MINUS_EXPR(rhs1, rhs2);
break;
case MULT_EXPR:
- RHS = EmitReg_BinOp(type, code, rhs1, rhs2, FLOAT_TYPE_P(type) ?
- Instruction::FMul : Instruction::Mul);
+ RHS = EmitReg_MULT_EXPR(rhs1, rhs2);
break;
case PLUS_EXPR:
RHS = EmitReg_PLUS_EXPR(rhs1, rhs2);
Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=94961&r1=94960&r2=94961&view=diff
==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Sun Jan 31 10:12:49 2010
@@ -645,6 +645,7 @@
Value *EmitReg_FLOOR_MOD_EXPR(tree_node *type, tree_node *op0,
tree_node *op1);
Value *EmitReg_MINUS_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_MULT_EXPR(tree_node *op0, tree_node *op1);
Value *EmitReg_PLUS_EXPR(tree_node *op0, tree_node *op1);
Value *EmitReg_POINTER_PLUS_EXPR(tree_node *type, tree_node *op0,
tree_node *op1);
More information about the llvm-commits
mailing list