aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Demangle/Demangle.h4
-rw-r--r--llvm/include/llvm/Demangle/MicrosoftDemangle.h4
-rw-r--r--llvm/include/llvm/IR/Mangler.h6
-rw-r--r--llvm/include/llvm/Target/TargetSelectionDAG.td6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp6
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp19
-rw-r--r--llvm/lib/IR/Mangler.cpp36
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td2
-rw-r--r--llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp7
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.cpp3
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp53
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp13
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td9
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp34
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td3
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp11
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp3
17 files changed, 138 insertions, 81 deletions
diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h
index fe129603c078..132e5088b551 100644
--- a/llvm/include/llvm/Demangle/Demangle.h
+++ b/llvm/include/llvm/Demangle/Demangle.h
@@ -10,6 +10,7 @@
#define LLVM_DEMANGLE_DEMANGLE_H
#include <cstddef>
+#include <optional>
#include <string>
#include <string_view>
@@ -54,6 +55,9 @@ enum MSDemangleFlags {
char *microsoftDemangle(std::string_view mangled_name, size_t *n_read,
int *status, MSDemangleFlags Flags = MSDF_None);
+std::optional<size_t>
+getArm64ECInsertionPointInMangledName(std::string_view MangledName);
+
// Demangles a Rust v0 mangled symbol.
char *rustDemangle(std::string_view MangledName);
diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
index 6891185a28e5..276efa760369 100644
--- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h
+++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
#define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
#include <cassert>
@@ -141,6 +142,9 @@ enum class FunctionIdentifierCodeGroup { Basic, Under, DoubleUnder };
// It has a set of functions to parse mangled symbols into Type instances.
// It also has a set of functions to convert Type instances to strings.
class Demangler {
+ friend std::optional<size_t>
+ llvm::getArm64ECInsertionPointInMangledName(std::string_view MangledName);
+
public:
Demangler() = default;
virtual ~Demangler() = default;
diff --git a/llvm/include/llvm/IR/Mangler.h b/llvm/include/llvm/IR/Mangler.h
index f28ffc961b6d..33af40c5ae98 100644
--- a/llvm/include/llvm/IR/Mangler.h
+++ b/llvm/include/llvm/IR/Mangler.h
@@ -56,6 +56,12 @@ void emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
std::optional<std::string> getArm64ECMangledFunctionName(StringRef Name);
std::optional<std::string> getArm64ECDemangledFunctionName(StringRef Name);
+/// Check if an ARM64EC function name is mangled.
+bool inline isArm64ECMangledFunctionName(StringRef Name) {
+ return Name[0] == '#' ||
+ (Name[0] == '?' && Name.find("@$$h") != StringRef::npos);
+}
+
} // End llvm namespace
#endif
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 46044aab79a8..e7895258438d 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -231,6 +231,10 @@ def SDTCatchret : SDTypeProfile<0, 2, [ // catchret
SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>
]>;
+def SDTCleanupret : SDTypeProfile<0, 1, [ // cleanupret
+ SDTCisVT<0, OtherVT>
+]>;
+
def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
def SDTUBSANTrap : SDTypeProfile<0, 1, []>; // ubsantrap
@@ -680,7 +684,7 @@ def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret,
[SDNPHasChain, SDNPSideEffect]>;
-def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>;
+def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTCleanupret, [SDNPHasChain]>;
def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 37b1131d2f8a..7fa3b8a73a41 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2155,8 +2155,10 @@ void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
FuncInfo.MBB->normalizeSuccProbs();
// Create the terminator node.
- SDValue Ret =
- DAG.getNode(ISD::CLEANUPRET, getCurSDLoc(), MVT::Other, getControlRoot());
+ MachineBasicBlock *CleanupPadMBB =
+ FuncInfo.MBBMap[I.getCleanupPad()->getParent()];
+ SDValue Ret = DAG.getNode(ISD::CLEANUPRET, getCurSDLoc(), MVT::Other,
+ getControlRoot(), DAG.getBasicBlock(CleanupPadMBB));
DAG.setRoot(Ret);
}
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index c5835e8c2e98..d35902a33376 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -24,6 +24,7 @@
#include <array>
#include <cctype>
#include <cstdio>
+#include <optional>
#include <string_view>
#include <tuple>
@@ -2424,6 +2425,24 @@ void Demangler::dumpBackReferences() {
std::printf("\n");
}
+std::optional<size_t>
+llvm::getArm64ECInsertionPointInMangledName(std::string_view MangledName) {
+ std::string_view ProcessedName{MangledName};
+
+ // We only support this for MSVC-style C++ symbols.
+ if (!consumeFront(ProcessedName, '?'))
+ return std::nullopt;
+
+ // The insertion point is just after the name of the symbol, so parse that to
+ // remove it from the processed name.
+ Demangler D;
+ D.demangleFullyQualifiedSymbolName(ProcessedName);
+ if (D.Error)
+ return std::nullopt;
+
+ return MangledName.length() - ProcessedName.length();
+}
+
char *llvm::microsoftDemangle(std::string_view MangledName, size_t *NMangled,
int *Status, MSDemangleFlags Flags) {
Demangler D;
diff --git a/llvm/lib/IR/Mangler.cpp b/llvm/lib/IR/Mangler.cpp
index e6c3ea9d5688..884739b3212c 100644
--- a/llvm/lib/IR/Mangler.cpp
+++ b/llvm/lib/IR/Mangler.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
@@ -291,30 +292,25 @@ void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
}
std::optional<std::string> llvm::getArm64ECMangledFunctionName(StringRef Name) {
- bool IsCppFn = Name[0] == '?';
- if (IsCppFn && Name.contains("$$h"))
- return std::nullopt;
- if (!IsCppFn && Name[0] == '#')
+ if (Name[0] != '?') {
+ // For non-C++ symbols, prefix the name with "#" unless it's already
+ // mangled.
+ if (Name[0] == '#')
+ return std::nullopt;
+ return std::optional<std::string>(("#" + Name).str());
+ }
+
+ // If the name contains $$h, then it is already mangled.
+ if (Name.contains("$$h"))
return std::nullopt;
- StringRef Prefix = "$$h";
- size_t InsertIdx = 0;
- if (IsCppFn) {
- InsertIdx = Name.find("@@");
- size_t ThreeAtSignsIdx = Name.find("@@@");
- if (InsertIdx != std::string::npos && InsertIdx != ThreeAtSignsIdx) {
- InsertIdx += 2;
- } else {
- InsertIdx = Name.find("@");
- if (InsertIdx != std::string::npos)
- InsertIdx++;
- }
- } else {
- Prefix = "#";
- }
+ // Ask the demangler where we should insert "$$h".
+ auto InsertIdx = getArm64ECInsertionPointInMangledName(Name);
+ if (!InsertIdx)
+ return std::nullopt;
return std::optional<std::string>(
- (Name.substr(0, InsertIdx) + Prefix + Name.substr(InsertIdx)).str());
+ (Name.substr(0, *InsertIdx) + "$$h" + Name.substr(*InsertIdx)).str());
}
std::optional<std::string>
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 1053ba924276..95f2f91f82bd 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -5159,7 +5159,7 @@ let isPseudo = 1 in {
//===----------------------------------------------------------------------===//
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
isCodeGenOnly = 1, isReturn = 1, isEHScopeReturn = 1, isPseudo = 1 in {
- def CLEANUPRET : Pseudo<(outs), (ins), [(cleanupret)]>, Sched<[]>;
+ def CLEANUPRET : Pseudo<(outs), (ins), [(cleanupret bb)]>, Sched<[]>;
let usesCustomInserter = 1 in
def CATCHRET : Pseudo<(outs), (ins am_brcond:$dst, am_brcond:$src), [(catchret bb:$dst, bb:$src)]>,
Sched<[]>;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 0863345b0c6d..c9636b2c7025 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -283,13 +283,18 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
Offset = 4;
}
+ // Save the number fixups.
+ size_t FixupStartIndex = Fixups.size();
+
// Emit an unconditional jump to the destination.
MCInst TmpInst =
MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
support::endian::write(CB, Binary, llvm::endianness::little);
- Fixups.clear();
+ // Drop any fixup added so we can add the correct one.
+ Fixups.resize(FixupStartIndex);
+
if (SrcSymbol.isExpr()) {
Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
MCFixupKind(RISCV::fixup_riscv_jal),
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index b2b88143354a..383393914a16 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -6653,7 +6653,8 @@ SDValue SystemZTargetLowering::combineTruncateExtract(
// Defer the creation of the bitcast from X to combineExtract,
// which might be able to optimize the extraction.
- VecVT = MVT::getVectorVT(MVT::getIntegerVT(TruncBytes * 8),
+ VecVT = EVT::getVectorVT(*DCI.DAG.getContext(),
+ MVT::getIntegerVT(TruncBytes * 8),
VecVT.getStoreSize() / TruncBytes);
EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
return combineExtract(DL, ResVT, VecVT, Vec, NewIndex, DCI, true);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 70b91c266c49..cd0aea313da0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -87,9 +87,8 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
const MachineBasicBlock *MBB);
unsigned getDelegateDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
const MachineBasicBlock *MBB);
- unsigned
- getRethrowDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
- const SmallVectorImpl<const MachineBasicBlock *> &EHPadStack);
+ unsigned getRethrowDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
+ const MachineBasicBlock *EHPadToRethrow);
void rewriteDepthImmediates(MachineFunction &MF);
void fixEndsAtEndOfFunction(MachineFunction &MF);
void cleanupFunctionData(MachineFunction &MF);
@@ -1612,34 +1611,13 @@ unsigned WebAssemblyCFGStackify::getDelegateDepth(
unsigned WebAssemblyCFGStackify::getRethrowDepth(
const SmallVectorImpl<EndMarkerInfo> &Stack,
- const SmallVectorImpl<const MachineBasicBlock *> &EHPadStack) {
+ const MachineBasicBlock *EHPadToRethrow) {
unsigned Depth = 0;
- // In our current implementation, rethrows always rethrow the exception caught
- // by the innermost enclosing catch. This means while traversing Stack in the
- // reverse direction, when we encounter END_TRY, we should check if the
- // END_TRY corresponds to the current innermost EH pad. For example:
- // try
- // ...
- // catch ;; (a)
- // try
- // rethrow 1 ;; (b)
- // catch ;; (c)
- // rethrow 0 ;; (d)
- // end ;; (e)
- // end ;; (f)
- //
- // When we are at 'rethrow' (d), while reversely traversing Stack the first
- // 'end' we encounter is the 'end' (e), which corresponds to the 'catch' (c).
- // And 'rethrow' (d) rethrows the exception caught by 'catch' (c), so we stop
- // there and the depth should be 0. But when we are at 'rethrow' (b), it
- // rethrows the exception caught by 'catch' (a), so when traversing Stack
- // reversely, we should skip the 'end' (e) and choose 'end' (f), which
- // corresponds to 'catch' (a).
for (auto X : reverse(Stack)) {
const MachineInstr *End = X.second;
if (End->getOpcode() == WebAssembly::END_TRY) {
auto *EHPad = TryToEHPad[EndToBegin[End]];
- if (EHPadStack.back() == EHPad)
+ if (EHPadToRethrow == EHPad)
break;
}
++Depth;
@@ -1651,7 +1629,6 @@ unsigned WebAssemblyCFGStackify::getRethrowDepth(
void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
// Now rewrite references to basic blocks to be depth immediates.
SmallVector<EndMarkerInfo, 8> Stack;
- SmallVector<const MachineBasicBlock *, 8> EHPadStack;
for (auto &MBB : reverse(MF)) {
for (MachineInstr &MI : llvm::reverse(MBB)) {
switch (MI.getOpcode()) {
@@ -1669,31 +1646,14 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
break;
case WebAssembly::END_BLOCK:
+ case WebAssembly::END_TRY:
Stack.push_back(std::make_pair(&MBB, &MI));
break;
- case WebAssembly::END_TRY: {
- // We handle DELEGATE in the default level, because DELEGATE has
- // immediate operands to rewrite.
- Stack.push_back(std::make_pair(&MBB, &MI));
- auto *EHPad = TryToEHPad[EndToBegin[&MI]];
- EHPadStack.push_back(EHPad);
- break;
- }
-
case WebAssembly::END_LOOP:
Stack.push_back(std::make_pair(EndToBegin[&MI]->getParent(), &MI));
break;
- case WebAssembly::CATCH:
- case WebAssembly::CATCH_ALL:
- EHPadStack.pop_back();
- break;
-
- case WebAssembly::RETHROW:
- MI.getOperand(0).setImm(getRethrowDepth(Stack, EHPadStack));
- break;
-
default:
if (MI.isTerminator()) {
// Rewrite MBB operands to be depth immediates.
@@ -1705,6 +1665,9 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
if (MI.getOpcode() == WebAssembly::DELEGATE)
MO = MachineOperand::CreateImm(
getDelegateDepth(Stack, MO.getMBB()));
+ else if (MI.getOpcode() == WebAssembly::RETHROW)
+ MO = MachineOperand::CreateImm(
+ getRethrowDepth(Stack, MO.getMBB()));
else
MO = MachineOperand::CreateImm(
getBranchDepth(Stack, MO.getMBB()));
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
index 0f06f54f219f..18545e92886a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
@@ -245,6 +245,19 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
ReplaceNode(Node, Throw);
return;
}
+ case Intrinsic::wasm_rethrow: {
+ // RETHROW's BB argument will be populated in LateEHPrepare. Just use a
+ // '0' as a placeholder for now.
+ MachineSDNode *Rethrow = CurDAG->getMachineNode(
+ WebAssembly::RETHROW, DL,
+ MVT::Other, // outchain type
+ {
+ CurDAG->getConstant(0, DL, MVT::i32), // placeholder
+ Node->getOperand(0) // inchain
+ });
+ ReplaceNode(Node, Rethrow);
+ return;
+ }
}
break;
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
index be6547007aaf..261277f8a02c 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
@@ -132,11 +132,9 @@ let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
defm THROW : I<(outs), (ins tag_op:$tag, variable_ops),
(outs), (ins tag_op:$tag), [],
"throw \t$tag", "throw \t$tag", 0x08>;
-defm RETHROW : NRI<(outs), (ins i32imm:$depth), [], "rethrow \t$depth", 0x09>;
+// $ehpad is the EH pad where the exception to rethrow has been caught.
+defm RETHROW : NRI<(outs), (ins bb_op:$ehpad), [], "rethrow \t$ehpad", 0x09>;
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
-// The depth argument will be computed in CFGStackify. We set it to 0 here for
-// now.
-def : Pat<(int_wasm_rethrow), (RETHROW 0)>;
// Region within which an exception is caught: try / end_try
let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
@@ -160,7 +158,8 @@ defm DELEGATE : NRI<(outs), (ins bb_op:$dst), [], "delegate \t $dst", 0x18>;
// Pseudo instructions: cleanupret / catchret
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
isPseudo = 1, isEHScopeReturn = 1 in {
- defm CLEANUPRET : NRI<(outs), (ins), [(cleanupret)], "cleanupret", 0>;
+ defm CLEANUPRET : NRI<(outs), (ins bb_op:$ehpad), [(cleanupret bb:$ehpad)],
+ "cleanupret", 0>;
defm CATCHRET : NRI<(outs), (ins bb_op:$dst, bb_op:$from),
[(catchret bb:$dst, bb:$from)], "catchret", 0>;
} // isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
index 94037b9ab189..b8f3bcb57f6b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -245,11 +245,39 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
Changed = true;
break;
}
+ case WebAssembly::RETHROW:
+ // These RETHROWs here were lowered from llvm.wasm.rethrow() intrinsics,
+ // generated in Clang for when an exception is not caught by the given
+ // type (e.g. catch (int)).
+ //
+ // RETHROW's BB argument is the EH pad where the exception to rethrow has
+ // been caught. (Until this point, RETHROW has just a '0' as a placeholder
+ // argument.) For these llvm.wasm.rethrow()s, we can safely assume the
+ // exception comes from the nearest dominating EH pad, because catch.start
+ // EH pad is structured like this:
+ //
+ // catch.start:
+ // catchpad ...
+ // %matches = compare ehselector with typeid
+ // br i1 %matches, label %catch, label %rethrow
+ //
+ // rethrow:
+ // ;; rethrows the exception caught in 'catch.start'
+ // call @llvm.wasm.rethrow()
+ TI->removeOperand(0);
+ TI->addOperand(MachineOperand::CreateMBB(getMatchingEHPad(TI)));
+ Changed = true;
+ break;
case WebAssembly::CLEANUPRET: {
- // Replace a cleanupret with a rethrow. For C++ support, currently
- // rethrow's immediate argument is always 0 (= the latest exception).
+ // CLEANUPRETs have the EH pad BB the exception to rethrow has been caught
+ // as an argument. Use it and change the instruction opcode to 'RETHROW'
+ // to make rethrowing instructions consistent.
+ //
+ // This is because we cannot safely assume that it is always the nearest
+ // dominating EH pad, in case there are code transformations such as
+ // inlining.
BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW))
- .addImm(0);
+ .addMBB(TI->getOperand(0).getMBB());
TI->eraseFromParent();
Changed = true;
break;
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 5a8177e2b360..9b13447754e4 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -195,7 +195,8 @@ def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
isCodeGenOnly = 1, isReturn = 1, isEHScopeReturn = 1 in {
- def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET", [(cleanupret)]>;
+ def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET",
+ [(cleanupret bb)]>;
// CATCHRET needs a custom inserter for SEH.
let usesCustomInserter = 1 in
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index e4895b59f4b4..cb052da79bb3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -334,6 +334,17 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
NewSelect->swapValues();
// Don't swap prof metadata, we didn't change the branch behavior.
NewSelect->setName(I->getName() + ".neg");
+ // Poison-generating flags should be dropped
+ Value *TV = NewSelect->getTrueValue();
+ Value *FV = NewSelect->getFalseValue();
+ if (match(TV, m_Neg(m_Specific(FV))))
+ cast<Instruction>(TV)->dropPoisonGeneratingFlags();
+ else if (match(FV, m_Neg(m_Specific(TV))))
+ cast<Instruction>(FV)->dropPoisonGeneratingFlags();
+ else {
+ cast<Instruction>(TV)->dropPoisonGeneratingFlags();
+ cast<Instruction>(FV)->dropPoisonGeneratingFlags();
+ }
Builder.Insert(NewSelect);
return NewSelect;
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 86411320ab24..b05a33c68889 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -513,7 +513,8 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
// especially bad when the PHIs are in the header of a loop.
bool NeededPhi = false;
- GEPNoWrapFlags NW = GEPNoWrapFlags::all();
+ // Remember flags of the first phi-operand getelementptr.
+ GEPNoWrapFlags NW = FirstInst->getNoWrapFlags();
// Scan to see if all operands are the same opcode, and all have one user.
for (Value *V : drop_begin(PN.incoming_values())) {