]> granicus.if.org Git - llvm/commitdiff
[ConstantFold] vector div/rem with any zero element in divisor is undef
authorSanjay Patel <spatel@rotateright.com>
Thu, 9 Mar 2017 20:42:30 +0000 (20:42 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 9 Mar 2017 20:42:30 +0000 (20:42 +0000)
Follow-up for:
https://reviews.llvm.org/D30665
https://reviews.llvm.org/rL297390

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

lib/IR/ConstantFold.cpp
test/Transforms/InstSimplify/div.ll
test/Transforms/InstSimplify/rem.ll

index 13241c3767524068478c6e4c750013f49073d3c4..dc7728a4841c21c7d210e96556db35f138073c3e 100644 (file)
@@ -1209,10 +1209,15 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
     SmallVector<Constant*, 16> Result;
     Type *Ty = IntegerType::get(VTy->getContext(), 32);
     for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
-      Constant *LHS =
-        ConstantExpr::getExtractElement(C1, ConstantInt::get(Ty, i));
-      Constant *RHS =
-        ConstantExpr::getExtractElement(C2, ConstantInt::get(Ty, i));
+      Constant *ExtractIdx = ConstantInt::get(Ty, i);
+      Constant *LHS = ConstantExpr::getExtractElement(C1, ExtractIdx);
+      Constant *RHS = ConstantExpr::getExtractElement(C2, ExtractIdx);
+
+      // If any element of a divisor vector is zero, the whole op is undef.
+      if ((Opcode == Instruction::SDiv || Opcode == Instruction::UDiv ||
+           Opcode == Instruction::SRem || Opcode == Instruction::URem) &&
+          RHS->isNullValue())
+        return UndefValue::get(VTy);
 
       Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
     }
index 6412bdfffe3bf3f7480a7a434e6c8d2edf296f19..560d3eea9331ab330f94003e729e697c2fb52bfe 100644 (file)
@@ -4,7 +4,7 @@
 
 define <2 x i8> @sdiv_zero_elt_vec_constfold(<2 x i8> %x) {
 ; CHECK-LABEL: @sdiv_zero_elt_vec_constfold(
-; CHECK-NEXT:    ret <2 x i8> <i8 undef, i8 0>
+; CHECK-NEXT:    ret <2 x i8> undef
 ;
   %div = sdiv <2 x i8> <i8 1, i8 2>, <i8 0, i8 -42>
   ret <2 x i8> %div
@@ -12,7 +12,7 @@ define <2 x i8> @sdiv_zero_elt_vec_constfold(<2 x i8> %x) {
 
 define <2 x i8> @udiv_zero_elt_vec_constfold(<2 x i8> %x) {
 ; CHECK-LABEL: @udiv_zero_elt_vec_constfold(
-; CHECK-NEXT:    ret <2 x i8> <i8 0, i8 undef>
+; CHECK-NEXT:    ret <2 x i8> undef
 ;
   %div = udiv <2 x i8> <i8 1, i8 2>, <i8 42, i8 0>
   ret <2 x i8> %div
index 90a0e65823508c062d31701b13004e57220e51f1..c60b728cad2a51c66da92e1c709994f93416dcbc 100644 (file)
@@ -5,7 +5,7 @@
 
 define <2 x i8> @srem_zero_elt_vec_constfold(<2 x i8> %x) {
 ; CHECK-LABEL: @srem_zero_elt_vec_constfold(
-; CHECK-NEXT:    ret <2 x i8> <i8 undef, i8 2>
+; CHECK-NEXT:    ret <2 x i8> undef
 ;
   %rem = srem <2 x i8> <i8 1, i8 2>, <i8 0, i8 -42>
   ret <2 x i8> %rem
@@ -13,7 +13,7 @@ define <2 x i8> @srem_zero_elt_vec_constfold(<2 x i8> %x) {
 
 define <2 x i8> @urem_zero_elt_vec_constfold(<2 x i8> %x) {
 ; CHECK-LABEL: @urem_zero_elt_vec_constfold(
-; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 undef>
+; CHECK-NEXT:    ret <2 x i8> undef
 ;
   %rem = urem <2 x i8> <i8 1, i8 2>, <i8 42, i8 0>
   ret <2 x i8> %rem