[llvm-branch-commits] [llvm][ProfDataUtils] provide getNumBranchWeights API (PR #90146)

2024-04-25 Thread Matthias Braun via llvm-branch-commits

https://github.com/MatzeB approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90146
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits

https://github.com/MatzeB edited https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits

https://github.com/MatzeB edited https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -4756,8 +4757,10 @@ void Verifier::visitProfMetadata(Instruction , MDNode 
*MD) {
 
   // Check consistency of !prof branch_weights metadata.
   if (ProfName.equals("branch_weights")) {
+unsigned int Offset = getBranchWeightOffset(I);
 if (isa()) {
-  Check(MD->getNumOperands() == 2 || MD->getNumOperands() == 3,
+  Check(MD->getNumOperands() == (1 + Offset) ||
+MD->getNumOperands() == (2 + Offset),

MatzeB wrote:

More opportunities for a possible `getNumBranchWeights(...)` API...

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -55,6 +55,20 @@ MDNode *getBranchWeightMDNode(const Instruction );
 /// Nullptr otherwise.
 MDNode *getValidBranchWeightMDNode(const Instruction );
 
+/// Check if Branch Weight Metadata has an "expected" field from an 
llvm.expect*
+/// intrinsic
+bool hasExpectedProvenance(const Instruction );

MatzeB wrote:

Hmm maybe this should somehow have the name "Weight" in the name, to not 
introduce confusion with alias-analysis things (at least I immediately think 
"alias analysis" when I see the word  "provenance") or find different term than 
"provenance"?

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -55,6 +55,20 @@ MDNode *getBranchWeightMDNode(const Instruction );
 /// Nullptr otherwise.
 MDNode *getValidBranchWeightMDNode(const Instruction );
 
+/// Check if Branch Weight Metadata has an "expected" field from an 
llvm.expect*
+/// intrinsic
+bool hasExpectedProvenance(const Instruction );
+
+/// Check if Branch Weight Metadata has an "expected" field from an 
llvm.expect*
+/// intrinsic
+bool hasExpectedProvenance(const MDNode *ProfileData);

MatzeB wrote:

FWIW: I usually prefer references like `const MDNode ` to indicate 
that an argument mustn't be `nullptr`. Though admittedly that remark comes too 
late given we already have other `const MDNode *` APIs in this header 
consistency is also worth something... So I guess I'm fine either way...

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -1210,12 +1210,22 @@ Instruction *Instruction::cloneImpl() const {
 
 void Instruction::swapProfMetadata() {
   MDNode *ProfileData = getBranchWeightMDNode(*this);
-  if (!ProfileData || ProfileData->getNumOperands() != 3)
+  if (!isBranchWeightMD(ProfileData))
 return;
 
-  // The first operand is the name. Fetch them backwards and build a new one.
-  Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
- ProfileData->getOperand(1)};
+  SmallVector Ops;
+  unsigned int FirstIdx = getBranchWeightOffset(ProfileData);
+  unsigned int SecondIdx = FirstIdx + 1;
+  // If there are more weights past the second, we can't swap them
+  if (ProfileData->getNumOperands() > SecondIdx + 1)
+return;
+  Ops.push_back(ProfileData->getOperand(0));
+  if (hasExpectedProvenance(ProfileData)) {
+Ops.push_back(ProfileData->getOperand(1));
+  }

MatzeB wrote:

Maybe this (I just have a feeling that leaving it more generic may help in case 
new sources are added one day):

```suggestion
  for (unsigned I = 0; I < FirstIdx; I++) {
 Ops.push_back(ProfileData->getOperand(I));
 }
```

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -1210,12 +1210,22 @@ Instruction *Instruction::cloneImpl() const {
 
 void Instruction::swapProfMetadata() {
   MDNode *ProfileData = getBranchWeightMDNode(*this);
-  if (!ProfileData || ProfileData->getNumOperands() != 3)
+  if (!isBranchWeightMD(ProfileData))
 return;
 
-  // The first operand is the name. Fetch them backwards and build a new one.
-  Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
- ProfileData->getOperand(1)};
+  SmallVector Ops;
+  unsigned int FirstIdx = getBranchWeightOffset(ProfileData);

MatzeB wrote:

Not a strong opinion, but I think most people just write `unsigned` in LLVM 
codebase...
```suggestion
  unsigned FirstIdx = getBranchWeightOffset(ProfileData);
```

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -5196,7 +5198,11 @@ void SwitchInstProfUpdateWrapper::init() {
   if (!ProfileData)
 return;
 
-  if (ProfileData->getNumOperands() != SI.getNumSuccessors() + 1) {
+  // FIXME: This check belongs in ProfDataUtils. Its almost equivalent to
+  // getValidBranchWeightMDNode(), but the need to use llvm_unreachable
+  // makes them slightly different.
+  if (ProfileData->getNumOperands() !=
+  SI.getNumSuccessors() + getBranchWeightOffset(ProfileData)) {

MatzeB wrote:

This seems simple enough to do something about it? Could for example add a 
`getNumBranchWeights()` API so this can become 
`getNumBranchWeights(ProfileData) != SI.getNumSuccessors()`?

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -106,6 +104,30 @@ bool hasValidBranchWeightMD(const Instruction ) {
   return getValidBranchWeightMDNode(I);
 }
 
+bool hasExpectedProvenance(const Instruction ) {
+  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
+  return hasExpectedProvenance(ProfileData);
+}
+
+bool hasExpectedProvenance(const MDNode *ProfileData) {
+  if (!isBranchWeightMD(ProfileData))
+return false;
+
+  auto *ProfDataName = dyn_cast(ProfileData->getOperand(1));
+  if (!ProfDataName)
+return false;
+  return ProfDataName->getString().equals("expected");
+}
+
+unsigned getBranchWeightOffset(const Instruction ) {
+  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
+  return getBranchWeightOffset(ProfileData);
+}
+
+unsigned getBranchWeightOffset(const MDNode *ProfileData) {
+  return hasExpectedProvenance(ProfileData) ? 2 : 1;
+}

MatzeB wrote:

What about a `hasBranchWeightProvenance()` API instead that just checks whether 
there is a string? That way you would get the same effect today but can skip 
the string comparison (and maybe get better behavior if there is a string that 
isn't actually "expected")

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits


@@ -55,6 +55,20 @@ MDNode *getBranchWeightMDNode(const Instruction );
 /// Nullptr otherwise.
 MDNode *getValidBranchWeightMDNode(const Instruction );
 
+/// Check if Branch Weight Metadata has an "expected" field from an 
llvm.expect*
+/// intrinsic
+bool hasExpectedProvenance(const Instruction );
+
+/// Check if Branch Weight Metadata has an "expected" field from an 
llvm.expect*
+/// intrinsic
+bool hasExpectedProvenance(const MDNode *ProfileData);
+
+/// Return the offset to the first branch weight data
+unsigned getBranchWeightOffset(const Instruction );

MatzeB wrote:

Is this API really helpful? Don't you have to get your hands on an `MDNode` 
anyway to do something useful with that offset?

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits

https://github.com/MatzeB commented:

I guess this is deliberately designed around a `bool IsExpected` rather than a 
more generic API. I guess I'm fine with it given the current patch, though I 
would bet it's just a question of time for someone to add more sources now... 
(so gotta make sure to turn the API into a generic one when there is more 
sources coming around)

Added a bunch of nitpicks, naming discussions etc. Though all-in-all this looks 
good to me.

https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm][IR] Extend BranchWeightMetadata to track provenance of weights (PR #86609)

2024-04-08 Thread Matthias Braun via llvm-branch-commits

https://github.com/MatzeB edited https://github.com/llvm/llvm-project/pull/86609
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [LivePhysRegs] Add callee-saved regs from MFI in addLiveOutsNoPristines. (PR #73553)

2023-11-27 Thread Matthias Braun via llvm-branch-commits

MatzeB wrote:

Looking at the `MachineOutliner` it seems to already be using `addLiveOuts()` 
so I must be missing something on why this change has any effect anyway...

https://github.com/llvm/llvm-project/pull/73553
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [LivePhysRegs] Add callee-saved regs from MFI in addLiveOutsNoPristines. (PR #73553)

2023-11-27 Thread Matthias Braun via llvm-branch-commits

MatzeB wrote:

Which code/pass is using `LivePhysRegs` that is causing you trouble here?

https://github.com/llvm/llvm-project/pull/73553
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [LivePhysRegs] Add callee-saved regs from MFI in addLiveOutsNoPristines. (PR #73553)

2023-11-27 Thread Matthias Braun via llvm-branch-commits

MatzeB wrote:

I still feel like I am missing something here, and it's been a while since I 
looked at this. But my impression is that LLVM modeling is "cheating" a bit in 
that technically all the callee-saves should be implicit-uses of the return 
instruction (and not live afterwards) but we don't model it that way and 
instead make them appear as live-outs of the return block? So doesn't seem like 
overestimating the liveness because of our current modeling?

If I'm reading your patch correctly it would mean we would start adding all 
pristine registers for the return block. I am just confused so far because this 
is happening in a function called `addLiveOutsNoPristines`...

https://github.com/llvm/llvm-project/pull/73553
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [LivePhysRegs] Add callee-saved regs from MFI in addLiveOutsNoPristines. (PR #73553)

2023-11-27 Thread Matthias Braun via llvm-branch-commits

MatzeB wrote:

I don't remember the situation on aarch64, but if by chance LR is modeled with 
this "pristine register" concept, then maybe the caller needs to use 
`addLiveIns()` rather than `addLiveInsNoPristines()`?

https://github.com/llvm/llvm-project/pull/73553
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [LivePhysRegs] Add callee-saved regs from MFI in addLiveOutsNoPristines. (PR #73553)

2023-11-27 Thread Matthias Braun via llvm-branch-commits

MatzeB wrote:

Is this about computing *live-outs* of the return block as the code suggests? 
(The summary currently talks about live-ins?)

https://github.com/llvm/llvm-project/pull/73553
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] ad25f8a - X86InstrInfo: Support immediates that are +1/-1 different in optimizeCompareInstr

2022-01-11 Thread Matthias Braun via llvm-branch-commits

Author: Matthias Braun
Date: 2022-01-11T09:07:29-08:00
New Revision: ad25f8a556d239d8b7d17383cf1a0771359521fd

URL: 
https://github.com/llvm/llvm-project/commit/ad25f8a556d239d8b7d17383cf1a0771359521fd
DIFF: 
https://github.com/llvm/llvm-project/commit/ad25f8a556d239d8b7d17383cf1a0771359521fd.diff

LOG: X86InstrInfo: Support immediates that are +1/-1 different in 
optimizeCompareInstr

This is a re-commit of e2c7ee0743592e39274e28dbe0d0c213ba342317 which
was reverted in a2a58d91e82db38fbdf88cc317dcb3753d79d492 and
ea81cea8163a1a0e54df42103ee1c657bbf03791. This includes a fix to
consistently check for EFLAGS being live-out. See phabricator
review.

Original Summary:

This extends `optimizeCompareInstr` to re-use previous comparison
results if the previous comparison was with an immediate that was 1
bigger or smaller. Example:

CMP x, 13
...
CMP x, 12   ; can be removed if we change the SETg
SETg ...; x > 12  changed to `SETge` (x >= 13) removing CMP

Motivation: This often happens because SelectionDAG canonicalization
tends to add/subtract 1 often when optimizing for fallthrough blocks.
Example for `x > C` the fallthrough optimization switches true/false
blocks with `!(x > C)` --> `x <= C` and canonicalization turns this into
`x < C + 1`.

Differential Revision: https://reviews.llvm.org/D110867

Added: 
llvm/test/CodeGen/X86/peep-test-5.ll

Modified: 
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86InstrInfo.h
llvm/test/CodeGen/X86/optimize-compare.mir
llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll

Removed: 




diff  --git a/llvm/lib/Target/X86/X86InstrInfo.cpp 
b/llvm/lib/Target/X86/X86InstrInfo.cpp
index c379aa8d9258..4dcd886fa3b2 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -4088,8 +4088,8 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr , 
Register ,
 bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr ,
 Register SrcReg, Register SrcReg2,
 int64_t ImmMask, int64_t ImmValue,
-const MachineInstr ,
-bool *IsSwapped) const {
+const MachineInstr , bool 
*IsSwapped,
+int64_t *ImmDelta) const {
   switch (OI.getOpcode()) {
   case X86::CMP64rr:
   case X86::CMP32rr:
@@ -4140,10 +4140,21 @@ bool X86InstrInfo::isRedundantFlagInstr(const 
MachineInstr ,
   int64_t OIMask;
   int64_t OIValue;
   if (analyzeCompare(OI, OISrcReg, OISrcReg2, OIMask, OIValue) &&
-  SrcReg == OISrcReg && ImmMask == OIMask && OIValue == ImmValue) {
-assert(SrcReg2 == X86::NoRegister && OISrcReg2 == X86::NoRegister &&
-   "should not have 2nd register");
-return true;
+  SrcReg == OISrcReg && ImmMask == OIMask) {
+if (OIValue == ImmValue) {
+  *ImmDelta = 0;
+  return true;
+} else if (static_cast(ImmValue) ==
+   static_cast(OIValue) - 1) {
+  *ImmDelta = -1;
+  return true;
+} else if (static_cast(ImmValue) ==
+   static_cast(OIValue) + 1) {
+  *ImmDelta = 1;
+  return true;
+} else {
+  return false;
+}
   }
 }
 return FlagI.isIdenticalTo(OI);
@@ -4393,6 +4404,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
, Register SrcReg,
   bool ShouldUpdateCC = false;
   bool IsSwapped = false;
   X86::CondCode NewCC = X86::COND_INVALID;
+  int64_t ImmDelta = 0;
 
   // Search backward from CmpInstr for the next instruction defining EFLAGS.
   const TargetRegisterInfo *TRI = ();
@@ -4439,7 +4451,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
, Register SrcReg,
 // ...   // EFLAGS not changed
 // cmp x, y  // <-- can be removed
 if (isRedundantFlagInstr(CmpInstr, SrcReg, SrcReg2, CmpMask, CmpValue,
- Inst, )) {
+ Inst, , )) {
   Sub = 
   break;
 }
@@ -4473,7 +4485,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
, Register SrcReg,
   // It is safe to remove CmpInstr if EFLAGS is redefined or killed.
   // If we are done with the basic block, we need to check whether EFLAGS is
   // live-out.
-  bool IsSafe = false;
+  bool FlagsMayLiveOut = true;
   SmallVector, 4> OpsToUpdate;
   MachineBasicBlock::iterator AfterCmpInstr =
   std::next(MachineBasicBlock::iterator(CmpInstr));
@@ -4483,7 +4495,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
, Register SrcReg,
 // We should check the usage if this instruction uses and updates EFLAGS.
 if (!UseEFLAGS && ModifyEFLAGS) {
   // It is safe to remove CmpInstr if EFLAGS is 

[llvm-branch-commits] [llvm] d72980a - Tests for D112754

2021-11-29 Thread Matthias Braun via llvm-branch-commits

Author: Matthias Braun
Date: 2021-11-29T16:02:06-08:00
New Revision: d72980acfa54375eb3415af72cd67e85faaac168

URL: 
https://github.com/llvm/llvm-project/commit/d72980acfa54375eb3415af72cd67e85faaac168
DIFF: 
https://github.com/llvm/llvm-project/commit/d72980acfa54375eb3415af72cd67e85faaac168.diff

LOG: Tests for D112754

Differential Revision: https://reviews.llvm.org/D113151

Added: 
llvm/test/CodeGen/X86/fold-masked-merge.ll

Modified: 


Removed: 




diff  --git a/llvm/test/CodeGen/X86/fold-masked-merge.ll 
b/llvm/test/CodeGen/X86/fold-masked-merge.ll
new file mode 100644
index 0..e26ec40afb3c6
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fold-masked-merge.ll
@@ -0,0 +1,287 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -o - %s -mtriple=x86_64-- | FileCheck %s 
--check-prefixes=CHECK,NOBMI
+; RUN: llc -o - %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s 
--check-prefixes=CHECK,BMI
+;
+; test that masked-merge code is generated as "xor;and;xor" sequence or
+; "andn ; and; or" if and-not is available.
+
+define i32 @masked_merge0(i32 %a0, i32 %a1, i32 %a2) {
+; NOBMI-LABEL: masked_merge0:
+; NOBMI:   # %bb.0:
+; NOBMI-NEXT:movl %edi, %eax
+; NOBMI-NEXT:andl %edi, %esi
+; NOBMI-NEXT:notl %eax
+; NOBMI-NEXT:andl %edx, %eax
+; NOBMI-NEXT:orl %esi, %eax
+; NOBMI-NEXT:retq
+;
+; BMI-LABEL: masked_merge0:
+; BMI:   # %bb.0:
+; BMI-NEXT:andl %edi, %esi
+; BMI-NEXT:andnl %edx, %edi, %eax
+; BMI-NEXT:orl %esi, %eax
+; BMI-NEXT:retq
+  %and0 = and i32 %a0, %a1
+  %not = xor i32 %a0, -1
+  %and1 = and i32 %not, %a2
+  %or = or i32 %and0, %and1
+  ret i32 %or
+}
+
+define i16 @masked_merge1(i16 %a0, i16 %a1, i16 %a2) {
+; NOBMI-LABEL: masked_merge1:
+; NOBMI:   # %bb.0:
+; NOBMI-NEXT:movl %edi, %eax
+; NOBMI-NEXT:andl %edi, %esi
+; NOBMI-NEXT:notl %eax
+; NOBMI-NEXT:andl %edx, %eax
+; NOBMI-NEXT:orl %esi, %eax
+; NOBMI-NEXT:# kill: def $ax killed $ax killed $eax
+; NOBMI-NEXT:retq
+;
+; BMI-LABEL: masked_merge1:
+; BMI:   # %bb.0:
+; BMI-NEXT:andl %edi, %esi
+; BMI-NEXT:andnl %edx, %edi, %eax
+; BMI-NEXT:orl %esi, %eax
+; BMI-NEXT:# kill: def $ax killed $ax killed $eax
+; BMI-NEXT:retq
+  %and0 = and i16 %a0, %a1
+  %not = xor i16 %a0, -1
+  %and1 = and i16 %a2, %not
+  %or = or i16 %and0, %and1
+  ret i16 %or
+}
+
+define i8 @masked_merge2(i8 %a0, i8 %a1, i8 %a2) {
+; CHECK-LABEL: masked_merge2:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:movl %edi, %eax
+; CHECK-NEXT:notb %al
+; CHECK-NEXT:andb %sil, %al
+; CHECK-NEXT:andb %dil, %sil
+; CHECK-NEXT:orb %sil, %al
+; CHECK-NEXT:retq
+  %not = xor i8 %a0, -1
+  %and0 = and i8 %not, %a1
+  %and1 = and i8 %a1, %a0
+  %or = or i8 %and0, %and1
+  ret i8 %or
+}
+
+define i64 @masked_merge3(i64 %a0, i64 %a1, i64 %a2) {
+; NOBMI-LABEL: masked_merge3:
+; NOBMI:   # %bb.0:
+; NOBMI-NEXT:movq %rdi, %rax
+; NOBMI-NEXT:notq %rsi
+; NOBMI-NEXT:notq %rdx
+; NOBMI-NEXT:andq %rdi, %rsi
+; NOBMI-NEXT:notq %rax
+; NOBMI-NEXT:andq %rdx, %rax
+; NOBMI-NEXT:orq %rsi, %rax
+; NOBMI-NEXT:retq
+;
+; BMI-LABEL: masked_merge3:
+; BMI:   # %bb.0:
+; BMI-NEXT:notq %rdx
+; BMI-NEXT:andnq %rdx, %rdi, %rcx
+; BMI-NEXT:andnq %rdi, %rsi, %rax
+; BMI-NEXT:orq %rcx, %rax
+; BMI-NEXT:retq
+  %v0 = xor i64 %a1, -1
+  %v1 = xor i64 %a2, -1
+  %not = xor i64 %a0, -1
+  %and0 = and i64 %not, %v1
+  %and1 = and i64 %v0, %a0
+  %or = or i64 %and0, %and1
+  ret i64 %or
+}
+
+; not a masked merge: there is no `not` operation.
+define i32 @not_a_masked_merge0(i32 %a0, i32 %a1, i32 %a2) {
+; CHECK-LABEL: not_a_masked_merge0:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:movl %edi, %eax
+; CHECK-NEXT:andl %edi, %esi
+; CHECK-NEXT:negl %eax
+; CHECK-NEXT:andl %edx, %eax
+; CHECK-NEXT:orl %esi, %eax
+; CHECK-NEXT:retq
+  %and0 = and i32 %a0, %a1
+  %not_a_not = sub i32 0, %a0
+  %and1 = and i32 %not_a_not, %a2
+  %or = or i32 %and0, %and1
+  ret i32 %or
+}
+
+; not a masked merge: `not` operand does not match another `and`-operand.
+define i32 @not_a_masked_merge1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
+; NOBMI-LABEL: not_a_masked_merge1:
+; NOBMI:   # %bb.0:
+; NOBMI-NEXT:movl %ecx, %eax
+; NOBMI-NEXT:andl %esi, %edi
+; NOBMI-NEXT:notl %eax
+; NOBMI-NEXT:andl %edx, %eax
+; NOBMI-NEXT:orl %edi, %eax
+; NOBMI-NEXT:retq
+;
+; BMI-LABEL: not_a_masked_merge1:
+; BMI:   # %bb.0:
+; BMI-NEXT:andl %esi, %edi
+; BMI-NEXT:andnl %edx, %ecx, %eax
+; BMI-NEXT:orl %edi, %eax
+; BMI-NEXT:retq
+  %and0 = and i32 %a0, %a1
+  %not = xor i32 %a3, -1
+  %and1 = and i32 %not, %a2
+  %or = or i32 %and0, %and1
+  ret i32 %or
+}
+
+; not a masked merge: one of the operands of `or` is not an `and`.
+define i32 @not_a_masked_merge2(i32 %a0, i32 %a1, 

[llvm-branch-commits] [llvm] 4db1cf5 - X86InstrInfo: Optimize more combinations of SUB+CMP

2021-10-28 Thread Matthias Braun via llvm-branch-commits

Author: Matthias Braun
Date: 2021-10-28T10:23:28-07:00
New Revision: 4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d

URL: 
https://github.com/llvm/llvm-project/commit/4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d
DIFF: 
https://github.com/llvm/llvm-project/commit/4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d.diff

LOG: X86InstrInfo: Optimize more combinations of SUB+CMP

`X86InstrInfo::optimizeCompareInstr` would only optimize a `SUB`
followed by a `CMP` in `isRedundantFlagInstr`. This extends the code to
also look for other combinations like `CMP`+`CMP`, `TEST`+`TEST`, `SUB
x,0`+`TEST`.

- Change `isRedundantFlagInstr` to run `analyzeCompareInstr` on the
  candidate instruction and compare the results. This normalizes things
  and gives consistent results for various comparisons (`CMP x, y`,
  `SUB x, y`) and immediate cases (`TEST x, x`, `SUB x, 0`,
  `CMP x, 0`...).
- Turn `isRedundantFlagInstr` into a member function so it can call
  `analyzeCompare`.  - We now also check `isRedundantFlagInstr` even if
  `IsCmpZero` is true, since we now have cases like `TEST`+`TEST`.

Differential Revision: https://reviews.llvm.org/D110865

Added: 


Modified: 
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86InstrInfo.h
llvm/test/CodeGen/X86/2007-02-16-BranchFold.ll
llvm/test/CodeGen/X86/optimize-compare.mir
llvm/test/CodeGen/X86/postalloc-coalescing.ll

Removed: 




diff  --git a/llvm/lib/Target/X86/X86InstrInfo.cpp 
b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 96180e2b2bf2..81e7184fa07a 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -4011,42 +4011,72 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr 
, Register ,
   return false;
 }
 
-/// Check whether the first instruction, whose only
-/// purpose is to update flags, can be made redundant.
-/// CMPrr can be made redundant by SUBrr if the operands are the same.
-/// This function can be extended later on.
-/// SrcReg, SrcRegs: register operands for FlagI.
-/// ImmValue: immediate for FlagI if it takes an immediate.
-inline static bool isRedundantFlagInstr(const MachineInstr ,
+bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr ,
 Register SrcReg, Register SrcReg2,
 int64_t ImmMask, int64_t ImmValue,
-const MachineInstr ) {
-  if (((FlagI.getOpcode() == X86::CMP64rr && OI.getOpcode() == X86::SUB64rr) ||
-   (FlagI.getOpcode() == X86::CMP32rr && OI.getOpcode() == X86::SUB32rr) ||
-   (FlagI.getOpcode() == X86::CMP16rr && OI.getOpcode() == X86::SUB16rr) ||
-   (FlagI.getOpcode() == X86::CMP8rr && OI.getOpcode() == X86::SUB8rr)) &&
-  ((OI.getOperand(1).getReg() == SrcReg &&
-OI.getOperand(2).getReg() == SrcReg2) ||
-   (OI.getOperand(1).getReg() == SrcReg2 &&
-OI.getOperand(2).getReg() == SrcReg)))
-return true;
-
-  if (ImmMask != 0 &&
-  ((FlagI.getOpcode() == X86::CMP64ri32 &&
-OI.getOpcode() == X86::SUB64ri32) ||
-   (FlagI.getOpcode() == X86::CMP64ri8 &&
-OI.getOpcode() == X86::SUB64ri8) ||
-   (FlagI.getOpcode() == X86::CMP32ri && OI.getOpcode() == X86::SUB32ri) ||
-   (FlagI.getOpcode() == X86::CMP32ri8 &&
-OI.getOpcode() == X86::SUB32ri8) ||
-   (FlagI.getOpcode() == X86::CMP16ri && OI.getOpcode() == X86::SUB16ri) ||
-   (FlagI.getOpcode() == X86::CMP16ri8 &&
-OI.getOpcode() == X86::SUB16ri8) ||
-   (FlagI.getOpcode() == X86::CMP8ri && OI.getOpcode() == X86::SUB8ri)) &&
-  OI.getOperand(1).getReg() == SrcReg &&
-  OI.getOperand(2).getImm() == ImmValue)
-return true;
-  return false;
+const MachineInstr ,
+bool *IsSwapped) const {
+  switch (OI.getOpcode()) {
+  case X86::CMP64rr:
+  case X86::CMP32rr:
+  case X86::CMP16rr:
+  case X86::CMP8rr:
+  case X86::SUB64rr:
+  case X86::SUB32rr:
+  case X86::SUB16rr:
+  case X86::SUB8rr: {
+Register OISrcReg;
+Register OISrcReg2;
+int64_t OIMask;
+int64_t OIValue;
+if (!analyzeCompare(OI, OISrcReg, OISrcReg2, OIMask, OIValue) ||
+OIMask != ImmMask || OIValue != ImmValue)
+  return false;
+if (SrcReg == OISrcReg && SrcReg2 == OISrcReg2) {
+  *IsSwapped = false;
+  return true;
+}
+if (SrcReg == OISrcReg2 && SrcReg2 == OISrcReg) {
+  *IsSwapped = true;
+  return true;
+}
+return false;
+  }
+  case X86::CMP64ri32:
+  case X86::CMP64ri8:
+  case X86::CMP32ri:
+  case X86::CMP32ri8:
+  case X86::CMP16ri:
+  case X86::CMP16ri8:
+  case X86::CMP8ri:
+  case X86::SUB64ri32:
+  case X86::SUB64ri8:
+  case X86::SUB32ri:
+  case X86::SUB32ri8:
+  case X86::SUB16ri:
+  case X86::SUB16ri8:
+  case X86::SUB8ri:
+  case X86::TEST64rr:
+  case X86::TEST32rr:
+  case X86::TEST16rr:
+  case 

[llvm-branch-commits] [llvm-branch] r294656 - ReleaseNotes.rst: Add a section about .mir testing

2017-02-09 Thread Matthias Braun via llvm-branch-commits
Author: matze
Date: Thu Feb  9 17:25:27 2017
New Revision: 294656

URL: http://llvm.org/viewvc/llvm-project?rev=294656=rev
Log:
ReleaseNotes.rst: Add a section about .mir testing

Modified:
llvm/branches/release_40/docs/ReleaseNotes.rst

Modified: llvm/branches/release_40/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/docs/ReleaseNotes.rst?rev=294656=294655=294656=diff
==
--- llvm/branches/release_40/docs/ReleaseNotes.rst (original)
+++ llvm/branches/release_40/docs/ReleaseNotes.rst Thu Feb  9 17:25:27 2017
@@ -75,6 +75,21 @@ Non-comprehensive list of changes in thi
* Significant build-time and binary-size improvements when compiling with
  debug info (-g).
 
+Code Generation Testing
+---
+
+Passes that work on the machine instruction representation can be tested with
+the .mir serialization format. ``llc`` supports the ``-run-pass``,
+``-stop-after``, ``-stop-before``, ``-start-after``, ``-start-before`` to to
+run a single pass of the code generation pipeline, or to stop or start the code
+generation pipeline at a given point.
+
+Additional information can be found in the :doc:`MIRLangRef`. The format is
+used by the tests ending in ``.mir`` in the ``test/CodeGen`` directory.
+
+This feature is available since 2015. It is used more often lately and was not
+mentioned in the release notes yet.
+
 Intrusive list API overhaul
 ---
 


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm-branch] r294630 - RegisterCoalescer: Cleanup joinReservedPhysReg(); NFC

2017-02-09 Thread Matthias Braun via llvm-branch-commits
Author: matze
Date: Thu Feb  9 15:45:29 2017
New Revision: 294630

URL: http://llvm.org/viewvc/llvm-project?rev=294630=rev
Log:
RegisterCoalescer: Cleanup joinReservedPhysReg(); NFC

Merging r293856:

- Factor out a common subexpression
- Add some helpful comments
- Fix printing of a register in a debug message

Preparation for http://llvm.org/PR31889

Modified:
llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp

Modified: llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp?rev=294630=294629=294630=diff
==
--- llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp Thu Feb  9 
15:45:29 2017
@@ -1556,9 +1556,10 @@ bool RegisterCoalescer::joinCopy(Machine
 
 bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair ) {
   unsigned DstReg = CP.getDstReg();
+  unsigned SrcReg = CP.getSrcReg();
   assert(CP.isPhys() && "Must be a physreg copy");
   assert(MRI->isReserved(DstReg) && "Not a reserved register");
-  LiveInterval  = LIS->getInterval(CP.getSrcReg());
+  LiveInterval  = LIS->getInterval(SrcReg);
   DEBUG(dbgs() << "\t\tRHS = " << RHS << '\n');
 
   assert(RHS.containsOneValue() && "Invalid join with reserved register");
@@ -1592,17 +1593,31 @@ bool RegisterCoalescer::joinReservedPhys
   // Delete the identity copy.
   MachineInstr *CopyMI;
   if (CP.isFlipped()) {
-CopyMI = MRI->getVRegDef(RHS.reg);
+// Physreg is copied into vreg
+//   %vregY = COPY %X
+//   ...  //< no other def of %X here
+//   use %vregY
+// =>
+//   ...
+//   use %X
+CopyMI = MRI->getVRegDef(SrcReg);
   } else {
-if (!MRI->hasOneNonDBGUse(RHS.reg)) {
+// VReg is copied into physreg:
+//   %vregX = def
+//   ... //< no other def or use of %Y here
+//   %Y = COPY %vregX
+// =>
+//   %Y = def
+//   ...
+if (!MRI->hasOneNonDBGUse(SrcReg)) {
   DEBUG(dbgs() << "\t\tMultiple vreg uses!\n");
   return false;
 }
 
-MachineInstr *DestMI = MRI->getVRegDef(RHS.reg);
-CopyMI = &*MRI->use_instr_nodbg_begin(RHS.reg);
-const SlotIndex CopyRegIdx = 
LIS->getInstructionIndex(*CopyMI).getRegSlot();
-const SlotIndex DestRegIdx = 
LIS->getInstructionIndex(*DestMI).getRegSlot();
+MachineInstr  = *MRI->getVRegDef(SrcReg);
+CopyMI = &*MRI->use_instr_nodbg_begin(SrcReg);
+SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot();
+SlotIndex DestRegIdx = LIS->getInstructionIndex(DestMI).getRegSlot();
 
 if (!MRI->isConstantPhysReg(DstReg)) {
   // We checked above that there are no interfering defs of the physical
@@ -1629,8 +1644,8 @@ bool RegisterCoalescer::joinReservedPhys
 
 // We're going to remove the copy which defines a physical reserved
 // register, so remove its valno, etc.
-DEBUG(dbgs() << "\t\tRemoving phys reg def of " << DstReg << " at "
-  << CopyRegIdx << "\n");
+DEBUG(dbgs() << "\t\tRemoving phys reg def of " << PrintReg(DstReg, TRI)
+  << " at " << CopyRegIdx << "\n");
 
 LIS->removePhysRegDefAt(DstReg, CopyRegIdx);
 // Create a new dead def at the new def location.


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm-branch] r294631 - RegisterCoalescer: Fix joinReservedPhysReg()

2017-02-09 Thread Matthias Braun via llvm-branch-commits
Author: matze
Date: Thu Feb  9 15:45:33 2017
New Revision: 294631

URL: http://llvm.org/viewvc/llvm-project?rev=294631=rev
Log:
RegisterCoalescer: Fix joinReservedPhysReg()

Merging r294268:

joinReservedPhysReg() can only deal with a liverange in a single basic
block when copying from a vreg into a physreg.

See also rdar://30306405

Differential Revision: https://reviews.llvm.org/D29436

Fixes http://llvm.org/PR31889

Modified:
llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp
llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir

Modified: llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp?rev=294631=294630=294631=diff
==
--- llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp Thu Feb  9 
15:45:33 2017
@@ -1614,6 +1614,11 @@ bool RegisterCoalescer::joinReservedPhys
   return false;
 }
 
+if (!LIS->intervalIsInOneMBB(RHS)) {
+  DEBUG(dbgs() << "\t\tComplex control flow!\n");
+  return false;
+}
+
 MachineInstr  = *MRI->getVRegDef(SrcReg);
 CopyMI = &*MRI->use_instr_nodbg_begin(SrcReg);
 SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot();

Modified: llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir
URL: 
http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir?rev=294631=294630=294631=diff
==
--- llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir (original)
+++ llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir Thu Feb  
9 15:45:33 2017
@@ -1,19 +1,24 @@
 # RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s 
-o - | FileCheck %s
 --- |
-  define void @func() { ret void }
+  define void @func0() { ret void }
+  define void @func1() { ret void }
+  define void @func2() { ret void }
 ...
 ---
 # Check coalescing of COPYs from reserved physregs.
-# CHECK-LABEL: name: func
-name: func
+# CHECK-LABEL: name: func0
+name: func0
 registers:
-  - { id: 0, class: gpr32 }
-  - { id: 1, class: gpr64 }
-  - { id: 2, class: gpr64 }
-  - { id: 3, class: gpr32 }
-  - { id: 4, class: gpr64 }
-  - { id: 5, class: gpr32 }
-  - { id: 6, class: xseqpairsclass }
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr64 }
+ - { id: 2, class: gpr64 }
+ - { id: 3, class: gpr32 }
+ - { id: 4, class: gpr64 }
+ - { id: 5, class: gpr32 }
+ - { id: 6, class: xseqpairsclass }
+ - { id: 7, class: gpr64 }
+ - { id: 8, class: gpr64sp }
+ - { id: 9, class: gpr64sp }
 body: |
   bb.0:
 ; We usually should not coalesce copies from allocatable physregs.
@@ -60,8 +65,74 @@ body: |
 ; Only coalesce when the source register is reserved as a whole (this is
 ; a limitation of the current code which cannot update liveness information
 ; of the non-reserved part).
-; CHECK: %6 = COPY %xzr_x0
+; CHECK: %6 = COPY %x28_fp
 ; CHECK: HINT 0, implicit %6
-%6 = COPY %xzr_x0
+%6 = COPY %x28_fp
 HINT 0, implicit %6
+
+; This can be coalesced.
+; CHECK: %fp = SUBXri %fp, 4, 0
+%8 = SUBXri %fp, 4, 0
+%fp = COPY %8
+
+; Cannot coalesce when there are reads of the physreg.
+; CHECK-NOT: %fp = SUBXri %fp, 8, 0
+; CHECK: %9 = SUBXri %fp, 8, 0
+; CHECK: STRXui %fp, %fp, 0
+; CHECK: %fp = COPY %9
+%9 = SUBXri %fp, 8, 0
+STRXui %fp, %fp, 0
+%fp = COPY %9
+...
+---
+# Check coalescing of COPYs from reserved physregs.
+# CHECK-LABEL: name: func1
+name: func1
+registers:
+ - { id: 0, class: gpr64sp }
+body: |
+  bb.0:
+successors: %bb.1, %bb.2
+; Cannot coalesce physreg because we have reads on other CFG paths (we
+; currently abort for any control flow)
+; CHECK-NOT: %fp = SUBXri
+; CHECK: %0 = SUBXri %fp, 12, 0
+; CHECK: CBZX undef %x0, %bb.1
+; CHECK: B %bb.2
+%0 = SUBXri %fp, 12, 0
+CBZX undef %x0, %bb.1
+B %bb.2
+
+  bb.1:
+%fp = COPY %0
+RET_ReallyLR
+
+  bb.2:
+STRXui %fp, %fp, 0
+RET_ReallyLR
+...
+---
+# CHECK-LABEL: name: func2
+name: func2
+registers:
+  - { id: 0, class: gpr64sp }
+body: |
+  bb.0:
+successors: %bb.1, %bb.2
+; We can coalesce copies from physreg to vreg across multiple blocks.
+; CHECK-NOT: COPY
+; CHECK: CBZX undef %x0, %bb.1
+; CHECK-NEXT: B %bb.2
+%0 = COPY %fp
+CBZX undef %x0, %bb.1
+B %bb.2
+
+  bb.1:
+; CHECK: STRXui undef %x0, %fp, 0
+; CHECK-NEXT: RET_ReallyLR
+STRXui undef %x0, %0, 0
+RET_ReallyLR
+
+  bb.2:
+RET_ReallyLR
 ...


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm-branch] r282615 - Cherry pick r281957 (see http://llvm.org/PR30463)

2016-09-28 Thread Matthias Braun via llvm-branch-commits
Author: matze
Date: Wed Sep 28 13:17:12 2016
New Revision: 282615

URL: http://llvm.org/viewvc/llvm-project?rev=282615=rev
Log:
Cherry pick r281957 (see http://llvm.org/PR30463)


Added:
llvm/branches/release_39/test/CodeGen/X86/branchfolding-undef.mir
  - copied unchanged from r281957, 
llvm/trunk/test/CodeGen/X86/branchfolding-undef.mir
Modified:
llvm/branches/release_39/   (props changed)
llvm/branches/release_39/lib/CodeGen/BranchFolding.cpp

Propchange: llvm/branches/release_39/
--
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 28 13:17:12 2016
@@ -1,3 +1,3 @@
 /llvm/branches/Apple/Pertwee:110850,110961
 /llvm/branches/type-system-rewrite:133420-134817
-/llvm/trunk:155241,275868-275870,275879,275898,275928,275935,275946,275978,275981,276015,276051,276077,276109,276119,276181,276209,276236-276237,276358,276364,276368,276389,276435,276438,276479,276510,276648,276676,276712,276740,276823,276956,276980,277093,277114,277135,277371,277399,277500,277504,277625,277691,277693,23,278002,278086,278133,278157,278343,278370,278413,278558-278559,278562,278569,278571,278573,278575,278584,278841,278900,278938,278999,279125,279268,279369,279647
+/llvm/trunk:155241,275868-275870,275879,275898,275928,275935,275946,275978,275981,276015,276051,276077,276109,276119,276181,276209,276236-276237,276358,276364,276368,276389,276435,276438,276479,276510,276648,276676,276712,276740,276823,276956,276980,277093,277114,277135,277371,277399,277500,277504,277625,277691,277693,23,278002,278086,278133,278157,278343,278370,278413,278558-278559,278562,278569,278571,278573,278575,278584,278841,278900,278938,278999,279125,279268,279369,279647,281957

Modified: llvm/branches/release_39/lib/CodeGen/BranchFolding.cpp
URL: 
http://llvm.org/viewvc/llvm-project/llvm/branches/release_39/lib/CodeGen/BranchFolding.cpp?rev=282615=282614=282615=diff
==
--- llvm/branches/release_39/lib/CodeGen/BranchFolding.cpp (original)
+++ llvm/branches/release_39/lib/CodeGen/BranchFolding.cpp Wed Sep 28 13:17:12 
2016
@@ -776,9 +776,8 @@ bool BranchFolder::CreateCommonTailOnlyB
 }
 
 static void
-mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
-  MachineBasicBlock ) {
-  // Merge MMOs from memory operations in the common block.
+mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
+MachineBasicBlock ) {
   MachineBasicBlock *MBB = MBBIStartPos->getParent();
   // Note CommonTailLen does not necessarily matches the size of
   // the common BB nor all its instructions because of debug
@@ -808,8 +807,18 @@ mergeMMOsFromMemoryOperations(MachineBas
"Reached BB end within common tail length!");
 assert(MBBICommon->isIdenticalTo(*MBBI) && "Expected matching MIIs!");
 
+// Merge MMOs from memory operations in the common block.
 if (MBBICommon->mayLoad() || MBBICommon->mayStore())
   MBBICommon->setMemRefs(MBBICommon->mergeMemRefsWith(*MBBI));
+// Drop undef flags if they aren't present in all merged instructions.
+for (unsigned I = 0, E = MBBICommon->getNumOperands(); I != E; ++I) {
+  MachineOperand  = MBBICommon->getOperand(I);
+  if (MO.isReg() && MO.isUndef()) {
+const MachineOperand  = MBBI->getOperand(I);
+if (!OtherMO.isUndef())
+  MO.setIsUndef(false);
+  }
+}
 
 ++MBBI;
 ++MBBICommon;
@@ -928,8 +937,8 @@ bool BranchFolder::TryTailMergeBlocks(Ma
 continue;
   DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber()
<< (i == e-1 ? "" : ", "));
-  // Merge MMOs from memory operations as needed.
-  mergeMMOsFromMemoryOperations(SameTails[i].getTailStartPos(), *MBB);
+  // Merge operations (MMOs, undef flags)
+  mergeOperations(SameTails[i].getTailStartPos(), *MBB);
   // Hack the end off BB i, making it jump to BB commonTailIndex instead.
   ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB);
   // BB i is no longer a predecessor of SuccBB; remove it from the 
worklist.


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits