ConstantFold: div undef, 0 should fold to undef, not zero
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 10 Dec 2014 09:14:55 +0000 (09:14 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 10 Dec 2014 09:14:55 +0000 (09:14 +0000)
Dividing by zero yields an undefined value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223924 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/ConstantFold.cpp
test/Transforms/InstSimplify/undef.ll

index 4cb22bc97a7d8c83b517ef57576aec909fcac250..cd409083afc6aea824ed8039d460851457355a71 100644 (file)
 #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::ConstantFoldBinaryInstruction(unsigned Opcode,
       // 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;
index 3742d7450af620f6367ad36d23c6e10254762340..5787badfd14e1316a78fb03118b42fa96ac27b1d 100644 (file)
@@ -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
+}