aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-11-01 22:56:22 +0800
committerGitHub <noreply@github.com>2024-11-01 22:56:22 +0800
commita77dedcacb4c5eb221395b69877981dd6ad98989 (patch)
treea0becf6eba8b2cfea196454400bc6e689a34cbbe /llvm/lib/IR/ConstantFold.cpp
parente577f14b670ee2ae6bb717133310b215be4331b3 (diff)
downloadllvm-a77dedcacb4c5eb221395b69877981dd6ad98989.zip
llvm-a77dedcacb4c5eb221395b69877981dd6ad98989.tar.gz
llvm-a77dedcacb4c5eb221395b69877981dd6ad98989.tar.bz2
[InstSimplify][InstCombine][ConstantFold] Move vector div/rem by zero fold to InstCombine (#114280)
Previously we fold `div/rem X, C` into `poison` if any element of the constant divisor `C` is zero or undef. However, it is incorrect when threading udiv over an vector select: https://alive2.llvm.org/ce/z/3Ninx5 ``` define <2 x i32> @vec_select_udiv_poison(<2 x i1> %x) { %sel = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 0, i32 1> %div = udiv <2 x i32> <i32 42, i32 -7>, %sel ret <2 x i32> %div } ``` In this case, `threadBinOpOverSelect` folds `udiv <i32 42, i32 -7>, <i32 -1, i32 -1>` and `udiv <i32 42, i32 -7>, <i32 0, i32 1>` into `zeroinitializer` and `poison`, respectively. One solution is to introduce a new flag indicating that we are threading over a vector select. But it requires to modify both `InstSimplify` and `ConstantFold`. However, this optimization doesn't provide benefits to real-world programs: https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/IR/ConstantFold.cpp.html#L908 https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp.html#L1107 This patch moves the fold into InstCombine to avoid breaking numerous existing tests. Fixes #114191 and #113866 (only poison-safety issue).
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp5
1 files changed, 0 insertions, 5 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 07dfbc4..c2780fa 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -902,11 +902,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
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 poison.
- if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
- return PoisonValue::get(VTy);
-
Constant *Res = ConstantExpr::isDesirableBinOp(Opcode)
? ConstantExpr::get(Opcode, LHS, RHS)
: ConstantFoldBinaryInstruction(Opcode, LHS, RHS);