diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/div.ll | 4 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/rem.ll | 4 |
3 files changed, 13 insertions, 8 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 13241c37675..dc7728a4841 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -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)); } diff --git a/llvm/test/Transforms/InstSimplify/div.ll b/llvm/test/Transforms/InstSimplify/div.ll index 6412bdfffe3..560d3eea933 100644 --- a/llvm/test/Transforms/InstSimplify/div.ll +++ b/llvm/test/Transforms/InstSimplify/div.ll @@ -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 diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll index 90a0e658235..c60b728cad2 100644 --- a/llvm/test/Transforms/InstSimplify/rem.ll +++ b/llvm/test/Transforms/InstSimplify/rem.ll @@ -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 |

