[llvm-branch-commits] [clang] b663278 - [OpenMP] Initial parsing/sema for the 'omp loop' construct

2021-10-28 Thread Mike Rice via llvm-branch-commits

Author: Mike Rice
Date: 2021-10-28T07:44:27-07:00
New Revision: b663278e084c9fff51275a670631784d3b9f730f

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

LOG: [OpenMP] Initial parsing/sema for the 'omp loop' construct

Adds basic parsing/sema/serialization support for the #pragma omp loop
directive.

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

Added: 
clang/test/OpenMP/generic_loop_ast_print.cpp
clang/test/OpenMP/generic_loop_messages.cpp

Modified: 
clang/include/clang-c/Index.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/StmtOpenMP.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/OpenMPKinds.h
clang/include/clang/Basic/StmtNodes.td
clang/include/clang/Sema/Sema.h
clang/include/clang/Serialization/ASTBitCodes.h
clang/lib/AST/StmtOpenMP.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/Basic/OpenMPKinds.cpp
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaExceptionSpec.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXCursor.cpp
llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 




diff  --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index b49acf6b58543..b0d7ef509c26f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2596,7 +2596,11 @@ enum CXCursorKind {
*/
   CXCursor_OMPMetaDirective = 294,
 
-  CXCursor_LastStmt = CXCursor_OMPMetaDirective,
+  /** OpenMP loop directive.
+   */
+  CXCursor_OMPGenericLoopDirective = 295,
+
+  CXCursor_LastStmt = CXCursor_OMPGenericLoopDirective,
 
   /**
* Cursor that represents the translation unit itself.

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index f200cd3920e67..74c49546c00bc 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3023,6 +3023,9 @@ DEF_TRAVERSE_STMT(OMPDispatchDirective,
 DEF_TRAVERSE_STMT(OMPMaskedDirective,
   { TRY_TO(TraverseOMPExecutableDirective(S)); })
 
+DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
+  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
 // OpenMP clauses.
 template 
 bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) {

diff  --git a/clang/include/clang/AST/StmtOpenMP.h 
b/clang/include/clang/AST/StmtOpenMP.h
index 60d47b93ba79f..48b2dce152a64 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -1144,7 +1144,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
 if (isOpenMPLoopBoundSharingDirective(Kind))
   return CombinedDistributeEnd;
 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) 
||
-isOpenMPDistributeDirective(Kind))
+isOpenMPGenericLoopDirective(Kind) || 
isOpenMPDistributeDirective(Kind))
   return WorksharingEnd;
 return DefaultEnd;
   }
@@ -1176,6 +1176,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
   }
   void setIsLastIterVariable(Expr *IL) {
 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+isOpenMPGenericLoopDirective(getDirectiveKind()) ||
 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
 isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1183,6 +1184,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
   }
   void setLowerBoundVariable(Expr *LB) {
 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+isOpenMPGenericLoopDirective(getDirectiveKind()) ||
 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
 isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1190,6 +1192,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
   }
   void setUpperBoundVariable(Expr *UB) {
 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+isOpenMPGenericLoopDirective(getDirectiveKind()) ||
 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
 isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1197,6 +1200,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
   }
   void setStrideVariable(Expr *ST) {
 assert((isOpenMPWorksharing

[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 
&MI, Register &SrcReg,
   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 &FlagI,
+bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI,
 Register SrcReg, Register SrcReg2,
 int64_t ImmMask, int64_t ImmValue,
-const MachineInstr &OI) {
-  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 &OI,
+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 X

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

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

Author: Matthias Braun
Date: 2021-10-28T10:23:29-07:00
New Revision: 26da34b3238a018af23951b6a559f26aa78c9b6e

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

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

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 81e7184fa07a..a9313bc8601a 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -4014,8 +4014,8 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, 
Register &SrcReg,
 bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI,
 Register SrcReg, Register SrcReg2,
 int64_t ImmMask, int64_t ImmValue,
-const MachineInstr &OI,
-bool *IsSwapped) const {
+const MachineInstr &OI, bool 
*IsSwapped,
+int64_t *ImmDelta) const {
   switch (OI.getOpcode()) {
   case X86::CMP64rr:
   case X86::CMP32rr:
@@ -4066,10 +4066,21 @@ bool X86InstrInfo::isRedundantFlagInstr(const 
MachineInstr &FlagI,
   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);
@@ -4319,6 +4330,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
&CmpInstr, 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 = &getRegisterInfo();
@@ -4365,7 +4377,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
&CmpInstr, Register SrcReg,
 // ...   // EFLAGS not changed
 // cmp x, y  // <-- can be removed
 if (isRedundantFlagInstr(CmpInstr, SrcReg, SrcReg2, CmpMask, CmpValue,
- Inst, &IsSwapped)) {
+ Inst, &IsSwapped, &ImmDelta)) {
   Sub = &Inst;
   break;
 }
@@ -4417,7 +4429,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
&CmpInstr, Register SrcReg,
 
 // EFLAGS is used by this instruction.
 X86::CondCode OldCC = X86::COND_INVALID;
-if (MI || IsSwapped) {
+if (MI || IsSwapped || ImmDelta != 0) {
   // We decode the condition code from opcode.
   if (Instr.isBranch())
 OldCC = X86::getCondFromBranch(Instr);
@@ -4470,9 +4482,59 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr 
&CmpInstr, Register SrcReg,
   // We swap the condition code and synthesize the new opcode.
   ReplacementCC = getSwappedCondition(OldCC);
   if (ReplacementCC == X86::COND_INVALID) return false;
+  ShouldUpdateCC = true;
+} else if (ImmDelta != 0) {
+  unsigned BitWidth = TRI->getRegSizeInBits(*MRI->getRegClass(SrcReg));
+  // Shift amount for min/max constants to adjust for 8/16/32 instruction
+  // s