[llvm-commits] [llvm] r134221 - in /llvm/trunk: lib/VMCore/ConstantFold.cpp test/Transforms/InstSimplify/binop.ll

Dan Gohman gohman at apple.com
Thu Jun 30 17:42:17 PDT 2011


Author: djg
Date: Thu Jun 30 19:42:17 2011
New Revision: 134221

URL: http://llvm.org/viewvc/llvm-project?rev=134221&view=rev
Log:
Improve constant folding of undef for binary operators.

Added:
    llvm/trunk/test/Transforms/InstSimplify/binop.ll
Modified:
    llvm/trunk/lib/VMCore/ConstantFold.cpp

Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=134221&r1=134220&r2=134221&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Thu Jun 30 19:42:17 2011
@@ -1014,20 +1014,38 @@
     case Instruction::Add:
     case Instruction::Sub:
       return UndefValue::get(C1->getType());
-    case Instruction::Mul:
     case Instruction::And:
+      if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef & undef -> undef
+        return C1;
+      return Constant::getNullValue(C1->getType());   // undef & X -> 0
+    case Instruction::Mul: {
+      ConstantInt *CI;
+      // X * undef -> undef   if X is odd or undef
+      if (((CI = dyn_cast<ConstantInt>(C1)) && CI->getValue()[0]) ||
+          ((CI = dyn_cast<ConstantInt>(C2)) && CI->getValue()[0]) ||
+          (isa<UndefValue>(C1) && isa<UndefValue>(C2)))
+        return UndefValue::get(C1->getType());
+
+      // X * undef -> 0       otherwise
       return Constant::getNullValue(C1->getType());
+    }
     case Instruction::UDiv:
     case Instruction::SDiv:
+      // undef / 1 -> undef
+      if (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv)
+        if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2))
+          if (CI2->isOne())
+            return C1;
+      // FALL THROUGH
     case Instruction::URem:
     case Instruction::SRem:
       if (!isa<UndefValue>(C2))                    // undef / X -> 0
         return Constant::getNullValue(C1->getType());
       return C2;                                   // X / undef -> undef
     case Instruction::Or:                          // X | undef -> -1
-      if (const VectorType *PTy = dyn_cast<VectorType>(C1->getType()))
-        return Constant::getAllOnesValue(PTy);
-      return Constant::getAllOnesValue(C1->getType());
+      if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef
+        return C1;
+      return Constant::getAllOnesValue(C1->getType()); // undef | X -> ~0
     case Instruction::LShr:
       if (isa<UndefValue>(C2) && isa<UndefValue>(C1))
         return C1;                                  // undef lshr undef -> undef
@@ -1041,6 +1059,8 @@
       else
         return C1;                                  // X ashr undef --> X
     case Instruction::Shl:
+      if (isa<UndefValue>(C2) && isa<UndefValue>(C1))
+        return C1;                                  // undef shl undef -> undef
       // undef << X -> 0   or   X << undef -> 0
       return Constant::getNullValue(C1->getType());
     }

Added: llvm/trunk/test/Transforms/InstSimplify/binop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/binop.ll?rev=134221&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/binop.ll (added)
+++ llvm/trunk/test/Transforms/InstSimplify/binop.ll Thu Jun 30 19:42:17 2011
@@ -0,0 +1,99 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+
+; @test0
+; CHECK: ret i64 undef
+define i64 @test0() {
+  %r = mul i64 undef, undef
+  ret i64 %r
+}
+
+; @test1
+; CHECK: ret i64 undef
+define i64 @test1() {
+  %r = mul i64 3, undef
+  ret i64 %r
+}
+
+; @test2
+; CHECK: ret i64 undef
+define i64 @test2() {
+  %r = mul i64 undef, 3
+  ret i64 %r
+}
+
+; @test3
+; CHECK: ret i64 0
+define i64 @test3() {
+  %r = mul i64 undef, 6
+  ret i64 %r
+}
+
+; @test4
+; CHECK: ret i64 0
+define i64 @test4() {
+  %r = mul i64 6, undef
+  ret i64 %r
+}
+
+; @test5
+; CHECK: ret i64 undef
+define i64 @test5() {
+  %r = and i64 undef, undef
+  ret i64 %r
+}
+
+; @test6
+; CHECK: ret i64 undef
+define i64 @test6() {
+  %r = or i64 undef, undef
+  ret i64 %r
+}
+
+; @test7
+; CHECK: ret i64 undef
+define i64 @test7() {
+  %r = udiv i64 undef, 1
+  ret i64 %r
+}
+
+; @test8
+; CHECK: ret i64 undef
+define i64 @test8() {
+  %r = sdiv i64 undef, 1
+  ret i64 %r
+}
+
+; @test9
+; CHECK: ret i64 0
+define i64 @test9() {
+  %r = urem i64 undef, 1
+  ret i64 %r
+}
+
+; @test10
+; CHECK: ret i64 0
+define i64 @test10() {
+  %r = srem i64 undef, 1
+  ret i64 %r
+}
+
+; @test11
+; CHECK: ret i64 undef
+define i64 @test11() {
+  %r = shl i64 undef, undef
+  ret i64 %r
+}
+
+; @test12
+; CHECK: ret i64 undef
+define i64 @test12() {
+  %r = ashr i64 undef, undef
+  ret i64 %r
+}
+
+; @test13
+; CHECK: ret i64 undef
+define i64 @test13() {
+  %r = lshr i64 undef, undef
+  ret i64 %r
+}





More information about the llvm-commits mailing list