[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