[llvm-commits] [llvm] r42035 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/srem.ll test/Transforms/InstCombine/urem.ll

Dan Gohman djg at cray.com
Mon Sep 17 10:31:57 PDT 2007


Author: djg
Date: Mon Sep 17 12:31:57 2007
New Revision: 42035

URL: http://llvm.org/viewvc/llvm-project?rev=42035&view=rev
Log:
Instcombine x-((x/y)*y) into a remainder operator.

Added:
    llvm/trunk/test/Transforms/InstCombine/srem.ll
    llvm/trunk/test/Transforms/InstCombine/urem.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=42035&r1=42034&r2=42035&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 17 12:31:57 2007
@@ -2257,6 +2257,17 @@
         Constant *CP1 = Subtract(ConstantInt::get(I.getType(), 1), C2);
         return BinaryOperator::createMul(Op0, CP1);
       }
+
+      // X - ((X / Y) * Y) --> X % Y
+      if (Op1I->getOpcode() == Instruction::Mul)
+        if (Instruction *I = dyn_cast<Instruction>(Op1I->getOperand(0)))
+          if (Op0 == I->getOperand(0) &&
+              Op1I->getOperand(1) == I->getOperand(1)) {
+            if (I->getOpcode() == Instruction::SDiv)
+              return BinaryOperator::createSRem(Op0, Op1I->getOperand(1));
+            if (I->getOpcode() == Instruction::UDiv)
+              return BinaryOperator::createURem(Op0, Op1I->getOperand(1));
+          }
     }
   }
 
@@ -2902,7 +2913,7 @@
 
 /// getICmpValue - This is the complement of getICmpCode, which turns an
 /// opcode and two operands into either a constant true or false, or a brand 
-/// new /// ICmp instruction. The sign is passed in to determine which kind
+/// new ICmp instruction. The sign is passed in to determine which kind
 /// of predicate to use in new icmp instructions.
 static Value *getICmpValue(bool sign, unsigned code, Value *LHS, Value *RHS) {
   switch (code) {

Added: llvm/trunk/test/Transforms/InstCombine/srem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/srem.ll?rev=42035&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/srem.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/srem.ll Mon Sep 17 12:31:57 2007
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep srem
+
+define i64 @foo(i64 %x1, i64 %y2) {
+	%r = sdiv i64 %x1, %y2
+	%r7 = mul i64 %r, %y2
+	%r8 = sub i64 %x1, %r7
+	ret i64 %r8
+}

Added: llvm/trunk/test/Transforms/InstCombine/urem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/urem.ll?rev=42035&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/urem.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/urem.ll Mon Sep 17 12:31:57 2007
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep urem
+
+define i64 @rem_unsigned(i64 %x1, i64 %y2) {
+	%r = udiv i64 %x1, %y2
+	%r7 = mul i64 %r, %y2
+	%r8 = sub i64 %x1, %r7
+	ret i64 %r8
+}





More information about the llvm-commits mailing list