[llvm] r223924 - ConstantFold: div undef, 0 should fold to undef, not zero

David Majnemer david.majnemer at gmail.com
Wed Dec 10 01:14:56 PST 2014


Author: majnemer
Date: Wed Dec 10 03:14:55 2014
New Revision: 223924

URL: http://llvm.org/viewvc/llvm-project?rev=223924&view=rev
Log:
ConstantFold: div undef, 0 should fold to undef, not zero

Dividing by zero yields an undefined value.

Modified:
    llvm/trunk/lib/IR/ConstantFold.cpp
    llvm/trunk/test/Transforms/InstSimplify/undef.ll

Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=223924&r1=223923&r2=223924&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Wed Dec 10 03:14:55 2014
@@ -27,12 +27,14 @@
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MathExtras.h"
 #include <limits>
 using namespace llvm;
+using namespace llvm::PatternMatch;
 
 //===----------------------------------------------------------------------===//
 //                ConstantFold*Instruction Implementations
@@ -923,19 +925,27 @@ Constant *llvm::ConstantFoldBinaryInstru
       // X * undef -> 0       otherwise
       return Constant::getNullValue(C1->getType());
     }
-    case Instruction::UDiv:
     case Instruction::SDiv:
+    case Instruction::UDiv:
+      // X / undef -> undef
+      if (match(C1, m_Zero()))
+        return C2;
+      // undef / 0 -> undef
       // undef / 1 -> undef
-      if (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv)
-        if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2))
-          if (CI2->isOne())
-            return C1;
-      // FALL THROUGH
+      if (match(C2, m_Zero()) || match(C2, m_One()))
+        return C1;
+      // undef / X -> 0       otherwise
+      return Constant::getNullValue(C1->getType());
     case Instruction::URem:
     case Instruction::SRem:
-      if (!isa<UndefValue>(C2))                    // undef / X -> 0
-        return Constant::getNullValue(C1->getType());
-      return C2;                                   // X / undef -> undef
+      // X % undef -> undef
+      if (match(C2, m_Undef()))
+        return C2;
+      // undef % 0 -> undef
+      if (match(C2, m_Zero()))
+        return C1;
+      // undef % X -> 0       otherwise
+      return Constant::getNullValue(C1->getType());
     case Instruction::Or:                          // X | undef -> -1
       if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef
         return C1;

Modified: llvm/trunk/test/Transforms/InstSimplify/undef.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/undef.ll?rev=223924&r1=223923&r2=223924&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/undef.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/undef.ll Wed Dec 10 03:14:55 2014
@@ -188,3 +188,10 @@ define i32 @test23(i32 %a) {
   %b = lshr exact i32 undef, %a
   ret i32 %b
 }
+
+; CHECK-LABEL: @test24
+; CHECK: ret i32 undef
+define i32 @test24(i32 %a) {
+  %b = udiv i32 undef, 0
+  ret i32 %b
+}





More information about the llvm-commits mailing list