[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