[llvm] Use DIExpression::foldConstantMath at the result of a Salvaged expression (PR #71721)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue May 14 17:25:53 PDT 2024
================
@@ -0,0 +1,281 @@
+//===- DIExpressionOptimizer.cpp - Constant folding of DIExpressions ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements functions to constant fold DIExpressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/DIExpressionOptimizer.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+
+bool isConstantVal(uint64_t Op) { return Op == dwarf::DW_OP_constu; }
+
+bool isNeutralElement(uint64_t Op, uint64_t Val) {
+ switch (Op) {
+ case dwarf::DW_OP_plus:
+ case dwarf::DW_OP_minus:
+ case dwarf::DW_OP_shl:
+ case dwarf::DW_OP_shr:
+ return Val == 0;
+ case dwarf::DW_OP_mul:
+ case dwarf::DW_OP_div:
+ return Val == 1;
+ default:
+ return false;
+ }
+}
+
+std::optional<uint64_t> foldOperationIfPossible(uint64_t Op, uint64_t Operand1,
+ uint64_t Operand2) {
+ bool ResultOverflowed;
+ switch (Op) {
+ case dwarf::DW_OP_plus: {
+ auto Result = SaturatingAdd(Operand1, Operand2, &ResultOverflowed);
+ if (ResultOverflowed)
+ return std::nullopt;
+ return Result;
+ }
+ case dwarf::DW_OP_minus: {
+ if (Operand1 < Operand2)
+ return std::nullopt;
+ return Operand1 - Operand2;
+ }
+ case dwarf::DW_OP_shl: {
+ if ((uint64_t)countl_zero(Operand1) < Operand2)
+ return std::nullopt;
+ return Operand1 << Operand2;
+ }
+ case dwarf::DW_OP_shr: {
+ if ((uint64_t)countr_zero(Operand1) < Operand2)
+ return std::nullopt;
+ return Operand1 >> Operand2;
+ }
+ case dwarf::DW_OP_mul: {
+ auto Result = SaturatingMultiply(Operand1, Operand2, &ResultOverflowed);
+ if (ResultOverflowed)
+ return std::nullopt;
+ return Result;
+ }
+ case dwarf::DW_OP_div: {
+ if (Operand2)
+ return Operand1 / Operand2;
+ return std::nullopt;
+ }
+ default:
+ return std::nullopt;
+ }
+}
+
+bool operationsAreFoldableAndCommutative(uint64_t Op1, uint64_t Op2) {
+ if (Op1 != Op2)
+ return false;
+ switch (Op1) {
----------------
MaskRay wrote:
`return xx == yy || xx == zz;`
https://github.com/llvm/llvm-project/pull/71721
More information about the llvm-commits
mailing list