Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GlobalIsel] Combine G_ADD and G_SUB with constants #97771

Merged
merged 6 commits into from
Aug 9, 2024

Conversation

tschuett
Copy link
Member

@tschuett tschuett commented Jul 4, 2024

No description provided.

@tschuett tschuett marked this pull request as ready for review July 4, 2024 22:07
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 4, 2024

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-llvm-globalisel

Author: Thorsten Schütt (tschuett)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/97771.diff

5 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h (+10)
  • (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+56-1)
  • (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+150)
  • (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-add-of-sub.mir (+19-22)
  • (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir (+117)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 37a56e12efcc3..b9286ddc0f7c0 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -886,6 +886,16 @@ class CombinerHelper {
 
   bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo);
 
+  bool matchFoldAPlusC1MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo);
+
+  bool matchFoldC2MinusAPlusC1(const MachineInstr &MI, BuildFnTy &MatchInfo);
+
+  bool matchFoldAMinusC1MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo);
+
+  bool matchFoldC1Minus2MinusC2(const MachineInstr &MI, BuildFnTy &MatchInfo);
+
+  bool matchFoldAMinusC2PlusC2(const MachineInstr &MI, BuildFnTy &MatchInfo);
+
 private:
   /// Checks for legality of an indexed variant of \p LdSt.
   bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3ef0636ebf1c7..f3c9db368eb4e 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1746,6 +1746,56 @@ def APlusBMinusCPlusA : GICombineRule<
           (G_ADD $root, $A, $sub1)),
    (apply (G_SUB $root, $B, $C))>;
 
+// fold (A+C1)-C2 -> A+(C1-C2)
+def APlusC1MinusC2: GICombineRule<
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
+   (match (G_CONSTANT $c2, $imm2),
+          (G_CONSTANT $c1, $imm1),
+          (G_ADD $add, $A, $c1),
+          (G_SUB $root, $add, $c2):$root,
+   [{ return Helper.matchFoldAPlusC1MinusC2(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
+// fold C2-(A+C1) -> (C2-C1)-A
+def C2MinusAPlusC1: GICombineRule<
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
+   (match (G_CONSTANT $c2, $imm2),
+          (G_CONSTANT $c1, $imm1),
+          (G_ADD $add, $A, $c1),
+          (G_SUB $root, $c2, $add):$root,
+   [{ return Helper.matchFoldC2MinusAPlusC1(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
+// fold (A-C1)-C2 -> A-(C1+C2)
+def AMinusC1MinusC2: GICombineRule<
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
+   (match (G_CONSTANT $c2, $imm2),
+          (G_CONSTANT $c1, $imm1),
+          (G_SUB $sub1, $A, $c1),
+          (G_SUB $root, $sub1, $c2):$root,
+   [{ return Helper.matchFoldAMinusC1MinusC2(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
+// fold (C1-A)-C2 -> (C1-C2)-A
+def C1Minus2MinusC2: GICombineRule<
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
+   (match (G_CONSTANT $c2, $imm2),
+          (G_CONSTANT $c1, $imm1),
+          (G_SUB $sub1, $c1, $A),
+          (G_SUB $root, $sub1, $c2):$root,
+   [{ return Helper.matchFoldC1Minus2MinusC2(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
+// fold ((A-C1)+C2) -> (A+(C2-C1))
+def AMinusC2PlusC2: GICombineRule<
+   (defs root:$root, build_fn_matchinfo:$matchinfo),
+   (match (G_CONSTANT $c2, $imm2),
+          (G_CONSTANT $c1, $imm1),
+          (G_SUB $sub, $A, $c1),
+          (G_ADD $root, $sub, $c2):$root,
+   [{ return Helper.matchFoldAMinusC2PlusC2(*${root}, ${matchinfo}); }]),
+   (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
 def integer_reassoc_combines: GICombineGroup<[
   ZeroMinusAPlusB,
   APlusZeroMinusB,
@@ -1754,7 +1804,12 @@ def integer_reassoc_combines: GICombineGroup<[
   AMinusBPlusCMinusA,
   AMinusBPlusBMinusC,
   APlusBMinusAplusC,
-  APlusBMinusCPlusA
+  APlusBMinusCPlusA,
+  APlusC1MinusC2,
+  C2MinusAPlusC1,
+  AMinusC1MinusC2,
+  C1Minus2MinusC2,
+  AMinusC2PlusC2
 ]>;
 
 def freeze_of_non_undef_non_poison : GICombineRule<
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index c27b882f17003..bb02a705ba89a 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7490,3 +7490,153 @@ bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
 
   return false;
 }
+
+bool CombinerHelper::matchFoldAPlusC1MinusC2(const MachineInstr &MI,
+                                             BuildFnTy &MatchInfo) {
+  // fold (A+C1)-C2 -> A+(C1-C2)
+  const GSub *Sub = cast<GSub>(&MI);
+  GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getLHSReg()));
+
+  if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub->getRHSReg(), MRI);
+  if (!MaybeC2)
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC1 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+  if (!MaybeC1)
+    return false;
+
+  Register Dst = Sub->getReg(0);
+  LLT DstTy = MRI.getType(Dst);
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    auto Const = B.buildConstant(DstTy, *MaybeC1 - *MaybeC2);
+    B.buildAdd(Dst, Add->getLHSReg(), Const);
+  };
+
+  return true;
+}
+
+bool CombinerHelper::matchFoldC2MinusAPlusC1(const MachineInstr &MI,
+                                             BuildFnTy &MatchInfo) {
+  // fold C2-(A+C1) -> (C2-C1)-A
+  const GSub *Sub = cast<GSub>(&MI);
+  GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getRHSReg()));
+
+  if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub->getLHSReg(), MRI);
+  if (!MaybeC2)
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC1 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+  if (!MaybeC1)
+    return false;
+
+  Register Dst = Sub->getReg(0);
+  LLT DstTy = MRI.getType(Dst);
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    auto Const = B.buildConstant(DstTy, *MaybeC2 - *MaybeC1);
+    B.buildSub(Dst, Const, Add->getLHSReg());
+  };
+
+  return true;
+}
+
+bool CombinerHelper::matchFoldAMinusC1MinusC2(const MachineInstr &MI,
+                                              BuildFnTy &MatchInfo) {
+  // fold (A-C1)-C2 -> A-(C1+C2)
+  const GSub *Sub1 = cast<GSub>(&MI);
+  GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+
+  if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub1->getRHSReg(), MRI);
+  if (!MaybeC2)
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub2->getRHSReg(), MRI);
+  if (!MaybeC1)
+    return false;
+
+  Register Dst = Sub1->getReg(0);
+  LLT DstTy = MRI.getType(Dst);
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    auto Const = B.buildConstant(DstTy, *MaybeC1 + *MaybeC2);
+    B.buildSub(Dst, Sub2->getLHSReg(), Const);
+  };
+
+  return true;
+}
+
+bool CombinerHelper::matchFoldC1Minus2MinusC2(const MachineInstr &MI,
+                                              BuildFnTy &MatchInfo) {
+  // fold (C1-A)-C2 -> (C1-C2)-A
+  const GSub *Sub1 = cast<GSub>(&MI);
+  GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+
+  if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC2 = getIConstantVRegVal(Sub1->getRHSReg(), MRI);
+  if (!MaybeC2)
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub2->getLHSReg(), MRI);
+  if (!MaybeC1)
+    return false;
+
+  Register Dst = Sub1->getReg(0);
+  LLT DstTy = MRI.getType(Dst);
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    auto Const = B.buildConstant(DstTy, *MaybeC1 - *MaybeC2);
+    B.buildSub(Dst, Const, Sub2->getRHSReg());
+  };
+
+  return true;
+}
+
+bool CombinerHelper::matchFoldAMinusC2PlusC2(const MachineInstr &MI,
+                                             BuildFnTy &MatchInfo) {
+  // fold ((A-C1)+C2) -> (A+(C2-C1))
+  const GAdd *Add = cast<GAdd>(&MI);
+  GSub *Sub = cast<GSub>(MRI.getVRegDef(Add->getLHSReg()));
+
+  if (!MRI.hasOneNonDBGUse(Sub->getReg(0)))
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC2 = getIConstantVRegVal(Add->getRHSReg(), MRI);
+  if (!MaybeC2)
+    return false;
+
+  // Cannot fail due to pattern.
+  std::optional<APInt> MaybeC1 = getIConstantVRegVal(Sub->getRHSReg(), MRI);
+  if (!MaybeC1)
+    return false;
+
+  Register Dst = Add->getReg(0);
+  LLT DstTy = MRI.getType(Dst);
+
+  MatchInfo = [=](MachineIRBuilder &B) {
+    auto Const = B.buildConstant(DstTy, *MaybeC2 - *MaybeC1);
+    B.buildAdd(Dst, Sub->getLHSReg(), Const);
+  };
+
+  return true;
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-add-of-sub.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add-of-sub.mir
index ac42d2da16d56..6bd1d996da85f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-add-of-sub.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-add-of-sub.mir
@@ -3,12 +3,12 @@
 
 ...
 ---
+# (x + y) - y -> x
 name:            simplify_to_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; (x + y) - y -> x
     ; CHECK-LABEL: name: simplify_to_x
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -23,12 +23,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  (x + y) - x -> y
 name:            simplify_to_y
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; (x + y) - x -> y
     ; CHECK-LABEL: name: simplify_to_y
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -43,12 +43,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# (x + 1) - 1 -> x
 name:            simplify_to_constant_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; (x + 1) - 1 -> x
     ; CHECK-LABEL: name: simplify_to_constant_x
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -64,12 +64,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# (x + y) - x -> y
 name:            simplify_to_constant_y
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; (x + y) - x -> y
     ; CHECK-LABEL: name: simplify_to_constant_y
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -85,12 +85,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# (x + y) - y -> x
 name:            vector_simplify_to_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $d0, $d1
-    ; (x + y) - y -> x
     ; CHECK-LABEL: name: vector_simplify_to_x
     ; CHECK: liveins: $d0, $d1
     ; CHECK-NEXT: {{  $}}
@@ -105,12 +105,12 @@ body:             |
     RET_ReallyLR implicit $d0
 ...
 ---
+# (x + 1) - 1 -> x
 name:            splat_simplify_to_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $d0, $d1
-    ; (x + 1) - 1 -> x
     ; CHECK-LABEL: name: splat_simplify_to_x
     ; CHECK: liveins: $d0, $d1
     ; CHECK-NEXT: {{  $}}
@@ -127,6 +127,7 @@ body:             |
     RET_ReallyLR implicit $d0
 ...
 ---
+#  (x + y) - x -> y
 name:            unique_registers_no_fold
 tracksRegLiveness: true
 body:             |
@@ -151,20 +152,18 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# (x + y) - x -> y
 name:            unique_constants_no_fold
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; (x + y) - x -> y
     ; CHECK-LABEL: name: unique_constants_no_fold
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %x1:_(s32) = G_CONSTANT i32 1
-    ; CHECK-NEXT: %x2:_(s32) = G_CONSTANT i32 2
     ; CHECK-NEXT: %y:_(s32) = COPY $w1
-    ; CHECK-NEXT: %add:_(s32) = G_ADD %y, %x1
-    ; CHECK-NEXT: %sub:_(s32) = G_SUB %add, %x2
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+    ; CHECK-NEXT: %sub:_(s32) = G_ADD %y, [[C]]
     ; CHECK-NEXT: $w0 = COPY %sub(s32)
     ; CHECK-NEXT: RET_ReallyLR implicit $w0
     %x1:_(s32) = G_CONSTANT i32 1
@@ -176,12 +175,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  x - (y + x) -> 0 - y
 name:            simplify_to_neg_y
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; x - (y + x) -> 0 - y
     ; CHECK-LABEL: name: simplify_to_neg_y
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -198,12 +197,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  y - (y + x) -> 0 - x
 name:            simplify_to_neg_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; y - (y + x) -> 0 - x
     ; CHECK-LABEL: name: simplify_to_neg_x
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -220,12 +219,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  x - (y + x) -> 0 - y
 name:            simplify_to_neg_y_constant
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; x - (y + x) -> 0 - y
     ; CHECK-LABEL: name: simplify_to_neg_y_constant
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -243,12 +242,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  y - (y + x) -> 0 - x
 name:            simplify_to_neg_x_constant
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; y - (y + x) -> 0 - x
     ; CHECK-LABEL: name: simplify_to_neg_x_constant
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
@@ -266,12 +265,12 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  y - (y + x) -> 0 - x
 name:            vector_simplify_to_neg_x
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $d0, $d1
-    ; y - (y + x) -> 0 - x
     ; CHECK-LABEL: name: vector_simplify_to_neg_x
     ; CHECK: liveins: $d0, $d1
     ; CHECK-NEXT: {{  $}}
@@ -289,12 +288,12 @@ body:             |
     RET_ReallyLR implicit $d0
 ...
 ---
+# x - (y + x) -> 0 - y
 name:            vector_simplify_to_neg_y_constant
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $d0, $d1
-    ; x - (y + x) -> 0 - y
     ; CHECK-LABEL: name: vector_simplify_to_neg_y_constant
     ; CHECK: liveins: $d0, $d1
     ; CHECK-NEXT: {{  $}}
@@ -314,12 +313,12 @@ body:             |
     RET_ReallyLR implicit $d0
 ...
 ---
+# y - (y + x) -> 0 - x
 name:            unique_registers_neg_no_fold
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; y - (y + x) -> 0 - x
     ; CHECK-LABEL: name: unique_registers_neg_no_fold
     ; CHECK: liveins: $w0, $w1, $w2
     ; CHECK-NEXT: {{  $}}
@@ -339,20 +338,18 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+#  x - (y + x) -> 0 - y
 name:            wrong_constant_neg_no_fold
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; x - (y + x) -> 0 - y
     ; CHECK-LABEL: name: wrong_constant_neg_no_fold
     ; CHECK: liveins: $w0, $w1
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %x1:_(s32) = G_CONSTANT i32 1
-    ; CHECK-NEXT: %x2:_(s32) = G_CONSTANT i32 2
     ; CHECK-NEXT: %y:_(s32) = COPY $w1
-    ; CHECK-NEXT: %add:_(s32) = G_ADD %y, %x1
-    ; CHECK-NEXT: %sub:_(s32) = G_SUB %x2, %add
+    ; CHECK-NEXT: %sub:_(s32) = G_SUB %x1, %y
     ; CHECK-NEXT: $w0 = COPY %sub(s32)
     ; CHECK-NEXT: RET_ReallyLR implicit $w0
     %x1:_(s32) = G_CONSTANT i32 1
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index be33f9f7b284b..2f10a497fa74c 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -250,3 +250,120 @@ body:             |
     %add:_(<2 x s64>) = G_ADD %a, %sub1
     $q0 = COPY %add
     RET_ReallyLR implicit $x0
+
+...
+---
+name:   APlusC1MinusC2
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: APlusC1MinusC2
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -2
+    ; CHECK-NEXT: %sub:_(s64) = G_ADD %a, [[C]]
+    ; CHECK-NEXT: $x0 = COPY %sub(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %c1:_(s64) = G_CONSTANT i64 5
+    %c2:_(s64) = G_CONSTANT i64 7
+    %add:_(s64) = G_ADD %a, %c1
+    %sub:_(s64) = G_SUB %add, %c2
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   C2MinusAPlusC1
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: C2MinusAPlusC1
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
+    ; CHECK-NEXT: $x0 = COPY %sub(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %c1:_(s64) = G_CONSTANT i64 4
+    %c2:_(s64) = G_CONSTANT i64 9
+    %add:_(s64) = G_ADD %a, %c1
+    %sub:_(s64) = G_SUB %c2, %add
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   AMinusC1MinusC2
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: AMinusC1MinusC2
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 71
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB %a, [[C]]
+    ; CHECK-NEXT: $x0 = COPY %sub(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %c1:_(s64) = G_CONSTANT i64 11
+    %c2:_(s64) = G_CONSTANT i64 60
+    %sub1:_(s64) = G_SUB %a, %c1
+    %sub:_(s64) = G_SUB %sub1, %c2
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:   C1Minus2MinusC2
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: C1Minus2MinusC2
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -49
+    ; CHECK-NEXT: %sub:_(s64) = G_SUB [[C]], %a
+    ; CHECK-NEXT: $x0 = COPY %sub(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %c1:_(s64) = G_CONSTANT i64 11
+    %c2:_(s64) = G_CONSTANT i64 60
+    %sub1:_(s64) = G_SUB %c1, %a
+    %sub:_(s64) = G_SUB %sub1, %c2
+    $x0 = COPY %sub
+    RET_ReallyLR implicit $x0
+
+
+...
+---
+name:   AMinusC2PlusC2
+body:             |
+  bb.0:
+    liveins: $w0, $w1
+
+    ; CHECK-LABEL: name: AMinusC2PlusC2
+    ; CHECK: liveins: $w0, $w1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %a:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 43
+    ; CHECK-NEXT: %add:_(s64) = G_ADD %a, [[C]]
+    ; CHECK-NEXT: $x0 = COPY %add(s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %a:_(s64) = COPY $x0
+    %c1:_(s64) = G_CONSTANT i64 13
+    %c2:_(s64) = G_CONSTANT i64 56
+    %sub:_(s64) = G_SUB %a, %c1
+    %add:_(s64) = G_ADD %sub, %c2
+    $x0 = COPY %add
+    RET_ReallyLR implicit $x0
+

@madhur13490
Copy link
Contributor

MIR test is useful but is it possible to add an IR test?

@tschuett
Copy link
Member Author

tschuett commented Jul 5, 2024

Anything is possible, but honestly I prefer MIR files for combines.

define i64 @AMinusC2PlusC2(i64 %a) {
; CHECK-LABEL: AMinusC2PlusC2:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sub x0, x0, #4
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sub is an add in MIR and the comment.

@tschuett
Copy link
Member Author

ping

1 similar comment
@tschuett
Copy link
Member Author

ping

Comment on lines 7505 to 7448
if (!MaybeC2)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are still checking it despite the comment that it cannot fail

Comment on lines 7510 to 7452
if (!MaybeC1)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7535 to 7476
if (!MaybeC2)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7540 to 7480
if (!MaybeC1)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7565 to 7504
if (!MaybeC2)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp Outdated Show resolved Hide resolved
Comment on lines 7595 to 7532
if (!MaybeC2)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7600 to 7536
if (!MaybeC1)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7625 to 7560
if (!MaybeC2)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment on lines 7630 to 7564
if (!MaybeC1)
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@tschuett
Copy link
Member Author

The comment is for documentation. I have to check optionals. I will never read from an optional before checking.

@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

The comment is for documentation. I have to check optionals. I will never read from an optional before checking.

I say remove them, and/or introduce a cannot fail API

@tschuett
Copy link
Member Author

I can remove the comments. The alternative would be to pass the G_CONSTANT s as MachineInstr to the match function and then manually extract the immediate, but this is really ugly.

@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

I can remove the comments. The alternative would be to pass the G_CONSTANT s as MachineInstr to the match function and then manually extract the immediate, but this is really ugly.

A null check that can never happen is misleading. Just don't check and let the assert in operator * do its job

@arsenm
Copy link
Contributor

arsenm commented Jul 19, 2024

I can remove the comments. The alternative would be to pass the G_CONSTANT s as MachineInstr to the match function and then manually extract the immediate, but this is really ugly.

That's possibly less ugly than the verbose constant lookup helper

@tschuett
Copy link
Member Author

I removed the comments.

@tschuett
Copy link
Member Author

tschuett commented Aug 3, 2024

Ping.

@tschuett
Copy link
Member Author

tschuett commented Aug 3, 2024

They are running commercial static analyzers over the project. They will scream when they find unchecked access to optionals.
We have our own unchecked access checker:
https://github.com/llvm/llvm-project/blob/main/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
The LLVM community decided to check optionals before accessing them.
Even if the probability of std::nullopt is a joke, we still need to check before accessing optionals.

This is the wrong approach.

@aemerson
Copy link
Contributor

aemerson commented Aug 5, 2024

I can sympathize with both of your sides. If we can guarantee that the constant is there why don't we just access it directly? What value does the getIConstantVRegVal() really bring there? Or we add a variant of that that just does what we want (which I thought we had already?).

Unchecked optionals has an off vibe, but ones that never fire also have a compile time impact.

@tschuett
Copy link
Member Author

tschuett commented Aug 5, 2024

I found

bool getCImmAsAPInt(const MachineInstr *MI, APInt &Result) {

which is also fallible and in an anonymous namespace.

The other option is to change the signature of the match functions:

bool CombinerHelper::matchFoldAPlusC1MinusC2(const MachineInstr &MI, const MachineInstr &C1, const MachineInstr &C2,
                                             BuildFnTy &MatchInfo) {

with the implication that C1 and C2 are G_CONSTANTs. I don't like because it is too low-level.

@aemerson
Copy link
Contributor

aemerson commented Aug 5, 2024

This is a common pattern and it's good if we can wholesale remove unnecessary optional checks across multiple combines by adding an API to do exactly what we want.

@tschuett
Copy link
Member Author

tschuett commented Aug 5, 2024

Thanks for chiming in. Surprise, I like getIConstantVRegVal. It goes through MRI and has to be fallible. The other option, I could see that tablegen creates a struct/class with the reconstructed pattern:
bool matchFoo(const FooPattern *Pattern, BuildFnTy &MatchInfo);

@aemerson
Copy link
Contributor

aemerson commented Aug 6, 2024

If the instruction is known to be a G_CONSTANT it doesn't have to be fallible. MRI.getVRegDef() is guaranteed to return an instance of it and if it doesn't it should be an assert. I don't see why that's a problem to add?

@tschuett
Copy link
Member Author

tschuett commented Aug 6, 2024

Firstly, please update the coding style section of the Combiner.rst with the outcome of the discussion.
I don't like the "If the instruction is known to be a G_CONSTANT ". The I know what I am doing might fail badly.
Warning does not compile:

APInt getIConstantFromReg(Register Reg, const MachineRegisterInfoI& MRI) {
  return cast<GIConstant>(MRI.getVRegDef(Reg))->getAPInt();
}

Bugs will make it fail badly. getIConstantVRegVal is more verbose, but gives better protection against errors.

In terms of compile-time, the next step is to hoist the oneuse checks into the MIR patterns.

@tschuett tschuett requested a review from aemerson August 6, 2024 04:56
@aemerson
Copy link
Contributor

aemerson commented Aug 7, 2024

Firstly, please update the coding style section of the Combiner.rst with the outcome of the discussion. I don't like the "If the instruction is known to be a G_CONSTANT ". The I know what I am doing might fail badly. Warning does not compile:

APInt getIConstantFromReg(Register Reg, const MachineRegisterInfoI& MRI) {
  return cast<GIConstant>(MRI.getVRegDef(Reg))->getAPInt();
}

Bugs will make it fail badly. getIConstantVRegVal is more verbose, but gives better protection against errors.

In terms of compile-time, the next step is to hoist the oneuse checks into the MIR patterns.

If it's expected that there is always a value in an optional or the compiler is in a bad internal state, then just bailing out and skipping the combine isn't solving anything. In fact I'd argue is actively harmful since it hides what should be a fatal error/assertion failure. So we should actually write code that expresses our intentions and preconditions, and using optional in this case doesn't express that accurately.

@aemerson
Copy link
Contributor

aemerson commented Aug 7, 2024

Firstly, please update the coding style section of the Combiner.rst with the outcome of the discussion.

This isn't specific to the combiner, it's a general principle.

@tschuett
Copy link
Member Author

tschuett commented Aug 7, 2024

Firstly, please update the coding style section of the Combiner.rst with the outcome of the discussion.

This isn't specific to the combiner, it's a general principle.

Fine. I thought something like, e.g., :
Methods for getting a G_CONSTANT from a register in decreasing priority:

  • getIConstantFromReg
  • getIConstantVRegVal
  • getIConstantVRegValWithLookThrough()

@aemerson
Copy link
Contributor

aemerson commented Aug 7, 2024

Perhaps instead of getIConstantFromReg() we have something like getKnownIConstantFromReg()? So it's clear from the name that it's expecting a guaranteed constant and can therefore safely assert inside. But I'll leave the naming to your judgement.

@tschuett
Copy link
Member Author

tschuett commented Aug 7, 2024

I am open for other names, but I like the pattern: APInt C2 = getIConstantFromReg(Sub->getRHSReg(), MRI);.

@tschuett tschuett requested a review from arsenm August 8, 2024 16:27
@aemerson
Copy link
Contributor

aemerson commented Aug 8, 2024

I did a build of CTMark with -Os and I don't see any change. What's motivating your patches here? Is there some benchmark that's getting better? Our work should be targeting closing our gap to SelectionDAG so that we can enable it by default.

@tschuett
Copy link
Member Author

tschuett commented Aug 9, 2024

https://github.com/llvm/llvm-project/blob/8cae9dcd4a45ac78b22c05eff96b0fee3e1c5e55/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L3870
I would be surprised, if there are combines that make a huge impact. It is the sum of many small combines that will give us performance.

@aemerson
Copy link
Contributor

aemerson commented Aug 9, 2024

That's true but implementing things that don't make any impact isn't going to get us closer at all. I'll do a build of the entire test suite to see what impact there is.

Our geomean deficit on Os is around 0.4-0.5% which suggests there are still relevant optimizations we can do that will noticeably move the needle.

I plan on starting work on that again soon but it's faster if we all align on the strategy instead of throwing darts at the wall.

; CHECK-LABEL: name: unique_constants_no_fold
; CHECK: liveins: $w0, $w1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %x1:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: %x2:_(s32) = G_CONSTANT i32 2
; CHECK-NEXT: %y:_(s32) = COPY $w1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a hit.
You never gave me https://youtu.be/8427bl_7k1g?t=2147.

@tschuett
Copy link
Member Author

tschuett commented Aug 9, 2024

Review is very efficient and goal oriented.

@aemerson
Copy link
Contributor

aemerson commented Aug 9, 2024

I put an assert into the combine to see when it fires. Essentially across the whole test suite I only see it hit in the MultiSource build variant of sqlite3 once, which saves 4 bytes across ~3.5k binaries. I will approve this but I really think it's not a good use of time to pursue this. If anything this might indicate we should remove these combines from SDAG for compile time reasons.

@tschuett tschuett merged commit 6b77531 into llvm:main Aug 9, 2024
8 checks passed
kutemeikito added a commit to kutemeikito/llvm-project that referenced this pull request Aug 10, 2024
* 'main' of https://github.com/llvm/llvm-project: (700 commits)
  [SandboxIR][NFC] SingleLLVMInstructionImpl class (llvm#102687)
  [ThinLTO]Clean up 'import-assume-unique-local' flag. (llvm#102424)
  [nsan] Make #include more conventional
  [SandboxIR][NFC] Use Tracker.emplaceIfTracking()
  [libc]  Moved range_reduction_double ifdef statement (llvm#102659)
  [libc] Fix CFP long double and add tests (llvm#102660)
  [TargetLowering] Handle vector types in expandFixedPointMul (llvm#102635)
  [compiler-rt][NFC] Replace environment variable with %t (llvm#102197)
  [UnitTests] Convert a test to use opaque pointers (llvm#102668)
  [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (llvm#101765)
  [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (llvm#102406)
  [mlir][bazel] remove extra blanks in mlir-tblgen test
  [NVPTX][NFC] Update tests to use bfloat type (llvm#101493)
  [mlir] Add support for parsing nested PassPipelineOptions (llvm#101118)
  [mlir][bazel] add missing td dependency in mlir-tblgen test
  [flang][cuda] Fix lib dependency
  [libc] Clean up remaining use of *_WIDTH macros in printf (llvm#102679)
  [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (llvm#102662)
  [SandboxIR] Implement the InsertElementInst class (llvm#102404)
  [libc] Fix use of cpp::numeric_limits<...>::digits (llvm#102674)
  [mlir][ODS] Verify type constraints in Types and Attributes (llvm#102326)
  [LTO] enable `ObjCARCContractPass` only on optimized build  (llvm#101114)
  [mlir][ODS] Consistent `cppType` / `cppClassName` usage (llvm#102657)
  [lldb] Move definition of SBSaveCoreOptions dtor out of header (llvm#102539)
  [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (llvm#102665)
  [clang] Implement -fptrauth-auth-traps. (llvm#102417)
  [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (llvm#102651)
  Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)"
  [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC
  Return available function types for BindingDecls. (llvm#102196)
  [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (llvm#102416)
  [RISCV] Remove riscv-experimental-rv64-legal-i32. (llvm#102509)
  [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (llvm#102496)
  [NVPTX] support switch statement with brx.idx (reland) (llvm#102550)
  [libc][newhdrgen]sorted function names in yaml (llvm#102544)
  [GlobalIsel] Combine G_ADD and G_SUB with constants (llvm#97771)
  Suppress spurious warnings due to R_RISCV_SET_ULEB128
  [scudo] Separated committed and decommitted entries. (llvm#101409)
  [MIPS] Fix missing ANDI optimization (llvm#97689)
  [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (llvm#102521)
  [asan] Switch allocator to dynamic base address (llvm#98511)
  [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)
  [libc][math][c23] Add fadd{l,f128} C23 math functions (llvm#102531)
  [mlir][bazel] revert bazel rule change for DLTITransformOps
  [msan] Support vst{2,3,4}_lane instructions (llvm#101215)
  Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)"
  [X86] pr57673.ll - generate MIR test checks
  [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (llvm#102584)
  [mlir][bazel] add bazel rule for DLTITransformOps
  OpenMPOpt: Remove dead include
  [IR] Add method to GlobalVariable to change type of initializer. (llvm#102553)
  [flang][cuda] Force default allocator in device code (llvm#102238)
  [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (llvm#102578)
  [MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)
  [AMDGPU][AsmParser][NFC] Remove a misleading comment. (llvm#102604)
  [Arm][AArch64][Clang] Respect function's branch protection attributes. (llvm#101978)
  [mlir] Verifier: steal bit to track seen instead of set. (llvm#102626)
  [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (llvm#100766)
  [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC.
  [gn] Give two scripts argparse.RawDescriptionHelpFormatter
  [bazel] Add missing dep for the SPIRVToLLVM target
  [Clang] Simplify specifying passes via -Xoffload-linker (llvm#102483)
  [bazel] Port for d45de80
  [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (llvm#82130)
  [Clang][OMPX] Add the code generation for multi-dim `num_teams` (llvm#101407)
  [ARM] Regenerate big-endian-vmov.ll. NFC
  [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (llvm#102616)
  [libc][math][c23] Add totalorderl function. (llvm#102564)
  [mlir][spirv] Support `memref` in `convert-to-spirv` pass (llvm#102534)
  [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (llvm#101664)
  Fix a unit test input file (llvm#102567)
  [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (llvm#102245)
  AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (llvm#102614)
  [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)
  [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (llvm#102105)
  [MemoryBuiltins] Handle allocator attributes on call-site
  LSV/test/AArch64: add missing lit.local.cfg; fix build (llvm#102607)
  Revert "Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)"
  [RISCV] Add Syntacore SCR5 RV32/64 processors definition (llvm#102285)
  [InstCombine] Remove unnecessary RUN line from test (NFC)
  [flang][OpenMP] Handle multiple ranges in `num_teams` clause (llvm#102535)
  [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (llvm#102361)
  [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (llvm#102573)
  [clang] Implement CWG2627 Bit-fields and narrowing conversions (llvm#78112)
  [NFC] Use references to avoid copying (llvm#99863)
  Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (llvm#100731)" (llvm#102457)
  [IRBuilder] Generate nuw GEPs for struct member accesses (llvm#99538)
  [bazel] Port for 9b06e25
  [CodeGen][NewPM] Improve start/stop pass error message CodeGenPassBuilder (llvm#102591)
  [AArch64] Implement TRBMPAM_EL1 system register (llvm#102485)
  [InstCombine] Fixing wrong select folding in vectors with undef elements (llvm#102244)
  [AArch64] Sink operands to fmuladd. (llvm#102297)
  LSV: document hang reported in llvm#37865 (llvm#102479)
  Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)
  [RISCV][clang] Remove bfloat base type in non-zvfbfmin vcreate (llvm#102146)
  [RISCV][clang] Add missing `zvfbfmin` to `vget_v` intrinsic (llvm#102149)
  [mlir][vector] Add mask elimination transform (llvm#99314)
  [Clang][Interp] Fix display of syntactically-invalid note for member function calls (llvm#102170)
  [bazel] Port for 3fffa6d
  [DebugInfo][RemoveDIs] Use iterator-inserters in clang (llvm#102006)
  ...

Signed-off-by: Edwiin Kusuma Jaya <[email protected]>
bwendling pushed a commit to bwendling/llvm-project that referenced this pull request Aug 15, 2024
BaLiKfromUA added a commit to BaLiKfromUA/clang-p2996 that referenced this pull request Aug 20, 2024
* [IRBuilder] Generate nuw GEPs for struct member accesses (#99538)

Generate nuw GEPs for struct member accesses, as inbounds + non-negative
implies nuw.

Regression tests are updated using update scripts where possible, and by
find + replace where not.

* Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (#100731)" (#102457)

This reverts commit 88accd9aaa20c6a30661c48cc2ca6dbbdf991ec0.

This change can be dropped in favor of just #102017.

* [NFC] Use references to avoid copying (#99863)

Modifying `auto` to `auto&` to avoid unnecessary copying

* [clang] Implement CWG2627 Bit-fields and narrowing conversions (#78112)

https://cplusplus.github.io/CWG/issues/2627.html

It is no longer a narrowing conversion when converting a bit-field to a
type smaller than the field's declared type if the bit-field has a width
small enough to fit in the target type. This includes integral
promotions (`long long i : 8` promoted to `int` is no longer narrowing,
allowing `c.i <=> c.i`) and list-initialization (`int n{ c.i };`)

Also applies back to C++11 as this is a defect report.

* [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (#102573)

Disables `vector.matrix_multiply` for scalable vectors. As per the docs:

>  This is the counterpart of llvm.matrix.multiply in MLIR

I'm not aware of any use of matrix-multiply intrinsics in the context of
scalable vectors, hence disabling.

* [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (#102361)

* [flang][OpenMP] Handle multiple ranges in `num_teams` clause (#102535)

Commit cee594cf36 added support to clang for multiple expressions in
`num_teams` clause. Add follow-up changes to flang.

* [InstCombine] Remove unnecessary RUN line from test (NFC)

As all the necessary information is encoded using attributes
nowadays, this test doesn't actually depend on the triple
anymore.

* [RISCV] Add Syntacore SCR5 RV32/64 processors definition (#102285)

Syntacore SCR5 is an entry-level Linux-capable 32/64-bit RISC-V
processor core.
Overview: https://syntacore.com/products/scr5

Scheduling model will be added in a subsequent PR.

Co-authored-by: Dmitrii Petrov <[email protected]>
Co-authored-by: Anton Afanasyev <[email protected]>

* Revert "Enable logf128 constant folding for hosts with 128bit floats (#96287)"

This reverts commit ccb2b011e577e861254f61df9c59494e9e122b38.

Causes buildbot failures, e.g. on ppc64le builders.

* LSV/test/AArch64: add missing lit.local.cfg; fix build (#102607)

Follow up on 199d6f2 (LSV: document hang reported in #37865) to fix the
build when omitting the AArch64 target. Add the missing lit.local.cfg.

* [MemoryBuiltins] Handle allocator attributes on call-site

We should handle allocator attributes not only on function
declarations, but also on the call-site. That way we can e.g.
also optimize cases where the allocator function is a virtual
function call.

This was already supported in some of the MemoryBuiltins helpers,
but not all of them. This adds support for allocsize, alloc-family
and allockind("free").

* [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (#102105)

The code-generator is currently not able to handle scalable vectors of
<vscale x 1 x eltty>. The usual "fix" for this until it is supported is
to mark the costs of loads/stores with an invalid cost, preventing the
vectorizer from vectorizing at those factors. But on rare occasions
loops do not contain load/stores, only reductions.

So whilst this is still unsupported return an invalid cost to avoid
selecting vscale x 1 VFs. The cost of a reduction is not currently used
by the vectorizer so this adds the cost to the add/mul/and/or/xor or
min/max that should feed the reduction. It includes reduction costs
too, for completeness. This change will be removed when code-generation
for these types is sufficiently reliable.

Fixes #99760

* Unnamed bitfields are not nonstatic data members.

* [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)

If nobuiltin is set, directly return nullptr instead of using a
separate out parameter and having all callers check this.

* AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (#102614)

This allows moving some tests relying on -stop-after=amdgpu-isel
to move to checking -stop-after=finalize-isel instead, which
will more reliably pass the verifier.

* [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (#102245)

* Fix a unit test input file (#102567)

I forgot to update the version info in the SDKSettings file when I
updated it to the real version relevant to the test.

* [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (#101664)

Add support in `-convert-gpu-to-llvm-spv` to convert `gpu.func` to
`llvm.func` operations.

- `spir_kernel`/`spir_func` calling conventions used for
kernels/functions.
- `workgroup` attributions encoded as additional `llvm.ptr<3>`
arguments.
- No attribute used to annotate kernels
- `reqd_work_group_size` attribute using to encode
`gpu.known_block_size`.
- `llvm.mlir.workgroup_attrib_size` used to encode workgroup attribution
sizes. This will be attached to the pointer argument workgroup
attributions lower to.

**Note**: A notable missing feature that will be addressed in a
follow-up PR is a `-use-bare-ptr-memref-call-conv` option to replace
MemRef arguments with bare pointers to the MemRef element types instead
of the current MemRef descriptor approach.

---------

Signed-off-by: Victor Perez <[email protected]>

* [mlir][spirv] Support `memref` in `convert-to-spirv` pass (#102534)

This PR adds conversion patterns for MemRef to the `convert-to-spirv`
pass, introduced in #95942. Conversions from MemRef memory space to
SPIR-V storage class were also included, and would run before the final
dialect conversion phase.

**Future Plans**
- Add tests for ops other than `memref.load` and `memref.store`

---------

Co-authored-by: Jakub Kuderski <[email protected]>

* [libc][math][c23] Add totalorderl function. (#102564)

* [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (#102616)

There's no need for them to have different types.

Part of <https://github.com/llvm/llvm-project/issues/62629>.

* [ARM] Regenerate big-endian-vmov.ll. NFC

* [Clang][OMPX] Add the code generation for multi-dim `num_teams` (#101407)

This patch adds the code generation support for multi-dim `num_teams`
clause when it is used with `target teams ompx_bare` construct.

* [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (#82130)

Prior to this patch, SelectionDAG generated aligned move onto stacks for
AVX registers when the function was marked as a no-realign-stack
function. This lead to misalignment between the stack and the
instruction generated. This patch fixes the issue. There was a similar
issue reported for `extractelement` which was fixed in
a6614ec5b7c1dbfc4b847884c5de780cf75e8e9c

Co-authored-by: Manish Kausik H <[email protected]>

* [bazel] Port for d45de8003a269066c9a9af871119a7c36eeb5aa3

* [Clang] Simplify specifying passes via -Xoffload-linker (#102483)

Make it possible to do things like the following, regardless of whether
the offload target is nvptx or amdgpu:

```
$ clang -O1 -g -fopenmp --offload-arch=native test.c                       \
    -Xoffload-linker -mllvm=-pass-remarks=inline                           \
    -Xoffload-linker -mllvm=-force-remove-attribute=g.internalized:noinline\
    -Xoffload-linker --lto-newpm-passes='forceattrs,default<O1>'           \
    -Xoffload-linker --lto-debug-pass-manager                              \
    -foffload-lto
```

To accomplish that:

- In clang-linker-wrapper, do not forward options via `-Wl` if they
might have literal commas. Use `-Xlinker` instead.
- In clang-nvlink-wrapper, accept `--lto-debug-pass-manager` and
`--lto-newpm-passes`.
- In clang-nvlink-wrapper, drop `-passes` because it's inconsistent with
the interface of `lld`, which is used instead of clang-nvlink-wrapper
when the target is amdgpu. Without this patch, `-passes` is passed to
`nvlink`, producing an error anyway.

---------

Co-authored-by: Joseph Huber <[email protected]>

* [bazel] Add missing dep for the SPIRVToLLVM target

* [gn] Give two scripts argparse.RawDescriptionHelpFormatter

Without this, the doc string is put in a single line. These
scripts have multi-line docstrings, so this makes their --help
output look much nicer.

Otherwise, no behavior change.

* [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC.

Inspired by #99418 (which hopefully we can replace this code with at some point)

* [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (#100766)

This PR addresses issues related to the handling of `init capture` with
parameter packs in Clang's
`LambdaScopeForCallOperatorInstantiationRAII`.

Previously, `addInstantiatedCapturesToScope` would add `init capture`
containing packs to the scope using the type of the `init capture` to
determine the expanded pack size. However, this approach resulted in a
pack size of 0 because `getType()->containsUnexpandedParameterPack()`
returns `false`. After extensive testing, it appears that the correct
pack size can only be inferred from `getInit`.

But `getInit` may reference parameters and `init capture` from an outer
lambda, as shown in the following example:

```cpp
auto L = [](auto... z) {
    return [... w = z](auto... y) {
        // ...
    };
};
```

To address this, `addInstantiatedCapturesToScope` in
`LambdaScopeForCallOperatorInstantiationRAII` should be called last.
Additionally, `addInstantiatedCapturesToScope` has been modified to only
add `init capture` to the scope. The previous implementation incorrectly
called `MakeInstantiatedLocalArgPack` for other non-init captures
containing packs, resulting in a pack size of 0.

### Impact

This patch affects scenarios where
`LambdaScopeForCallOperatorInstantiationRAII` is passed with
`ShouldAddDeclsFromParentScope = false`, preventing the correct addition
of the current lambda's `init capture` to the scope. There are two main
scenarios for `ShouldAddDeclsFromParentScope = false`:

1. **Constraints**: Sometimes constraints are instantiated in place
rather than delayed. In this case,
`LambdaScopeForCallOperatorInstantiationRAII` does not need to add `init
capture` to the scope.
2. **`noexcept` Expressions**: The expressions inside `noexcept` have
already been transformed, and the packs referenced within have been
expanded. Only `RebuildLambdaInfo` needs to add the expanded captures to
the scope, without requiring `addInstantiatedCapturesToScope` from
`LambdaScopeForCallOperatorInstantiationRAII`.

### Considerations

An alternative approach could involve adding a data structure within the
lambda to record the expanded size of the `init capture` pack. However,
this would increase the lambda's size and require extensive
modifications.

This PR is a prerequisite for implmenting
https://github.com/llvm/llvm-project/issues/61426

* [mlir] Verifier: steal bit to track seen instead of set. (#102626)

Tracking a set containing every block and operation visited can become
very expensive and is unnecessary.

Co-authored-by: Will Dietz <[email protected]>

* [Arm][AArch64][Clang] Respect function's branch protection attributes. (#101978)

Default attributes assigned to all functions according to the command
line parameters. Some functions might have their own attributes and we
need to set or remove attributes accordingly.
Tests are updated to test this scenarios too.

* [AMDGPU][AsmParser][NFC] Remove a misleading comment. (#102604)

The work of ParseRegularReg() should remain to be parsing the register
as it was specified, and not to try translate it to anything else.

It's up to operand predicates to decide on what is and is not an
acceptable register for an operand, including considering its expected
register class, and for the rest of the AsmParser infrastructure to
handle it respectively from there on.

* [MLIR][DLTI][Transform] Introduce transform.dlti.query (#101561)

This transform op makes it possible to query attributes associated to IR
by means of the DLTI dialect.

The op takes both a `key` and a target `op` to perform the query at.
Facility functions automatically find the closest ancestor op which
defines the appropriate DLTI interface or has an attribute implementing
a DLTI interface. By default the lookup uses the data layout interfaces
of DLTI. If the optional `device` parameter is provided, the lookup
happens with respect to the interfaces for TargetSystemSpec and
TargetDeviceSpec.

This op uses new free-standing functions in the `dlti` namespace to not
only look up specifications via the `DataLayoutSpecOpInterface` and on
`ModuleOp`s but also on any ancestor op that has an appropriate DLTI
attribute.

* [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (#102578)

* [flang][cuda] Force default allocator in device code (#102238)

* [IR] Add method to GlobalVariable to change type of initializer. (#102553)

With opaque pointers, nothing directly uses the value type, so we can
mutate it if we want. This avoid doing a complicated RAUW dance.

* OpenMPOpt: Remove dead include

* [mlir][bazel] add bazel rule for DLTITransformOps

* [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (#102584)

Move tests that exercise DropUnitDimFromElementwiseOps and
DropUnitDimsFromTransposeOp to a dedicated file.

While these patterns are collected under populateFlattenVectorTransferPatterns
(and are tested via -test-vector-transfer-flatten-patterns), they can actually
be tested without the xfer Ops, and hence the split.

Note, this is mostly just moving tests from one file to another. The only real
change is the removal of the following check-lines:

```mlir
//   CHECK-128B-NOT:   memref.collapse_shape
```

These were added specifically to check the "flattening" logic (which introduces
`memref.collapse_shape`). However, these tests were never meant to test that
logic (in fact, that's the reason I am moving them to a different file) and
hence are being removed as copy&paste errors.

I also removed the following TODO:

```mlir
/// TODO: Potential duplication with tests from:
///   * "vector-dropleadunitdim-transforms.mlir"
///   * "vector-transfer-drop-unit-dims-patterns.mlir"
```
I've checked what patterns are triggered in those test files and neither
DropUnitDimFromElementwiseOps nor DropUnitDimsFromTransposeOp does.

* [X86] pr57673.ll - generate MIR test checks

* Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (#101561)"

This reverts commit 8f21ff9bd89fb7c8bbfdc4426b65dcd9ababf3ce.

Crashed CI builds

* [msan] Support vst{2,3,4}_lane instructions (#101215)

This generalizes MSan's Arm NEON vst support, to include the
lane-specific variants.

This also updates the test from
https://github.com/llvm/llvm-project/pull/100645.

* [mlir][bazel] revert bazel rule change for DLTITransformOps

* [libc][math][c23] Add fadd{l,f128} C23 math functions (#102531)

Co-authored-by: OverMighty <[email protected]>

* [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (#102086)

Currently `AMDGPUAttributorPass` is registered in default optimizer
pipeline.
This will allow the pass to run in default pipeline as well as at
thinLTO post
link stage. However, it will not run in full LTO post link stage. This
patch
moves it to full LTO.

* [asan] Switch allocator to dynamic base address (#98511)

This ports a fix from memprof (https://github.com/llvm/llvm-project/pull/98510), which has a shadow mapping that is similar to ASan (8 bytes of shadow memory per 64 bytes of app memory). This patch changes the allocator to dynamically choose a base address, as suggested by Vitaly for memprof. This simplifies ASan's #ifdef's and avoids potential conflict in the event that ASan were to switch to a dynamic shadow offset in the future [1].

[1] Since shadow memory is mapped before the allocator is mapped:
- dynamic shadow and fixed allocator (old memprof): could fail if
"unlucky" (e.g., https://lab.llvm.org/buildbot/#/builders/66/builds/1361/steps/17/logs/stdio)
- dynamic shadow and dynamic allocator (HWASan; current memprof): always works
- fixed shadow and fixed allocator (current ASan): always works, if
constants are carefully chosen
- fixed shadow and dynamic allocator (ASan with this patch): always works

* [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (#102521)

When working on very busy systems, check-offload frequently fails many
tests with this diagnostic:

```
clang: error: cannot determine amdgcn architecture: /tmp/llvm/build/bin/amdgpu-arch: Child timed out: ; consider passing it via '-march'
```

This patch accepts the environment variable
`CLANG_TOOLCHAIN_PROGRAM_TIMEOUT` to set the timeout. It also increases
the timeout from 10 to 60 seconds.

* [MIPS] Fix missing ANDI optimization (#97689)

1. Add MipsPat to optimize (andi (srl (truncate i64 $1), x), y) to (andi
(truncate (dsrl i64 $1, x)), y).
2. Add MipsPat to optimize (ext (truncate i64 $1), x, y) to (truncate
(dext i64 $1, x, y)).

The assembly result is the same as gcc.

Fixes https://github.com/llvm/llvm-project/issues/42826

* [scudo] Separated committed and decommitted entries. (#101409)

Initially, the LRU list stored all mapped entries with no distinction
between the committed (non-madvise()'d) entries and decommitted
(madvise()'d) entries. Now these two types of entries re separated into
two lists, allowing future cache logic to branch depending on whether or
not entries are committed or decommitted. Furthermore, the retrieval
algorithm will prioritize committed entries over decommitted entries.
Specifically, committed entries that satisfy the MaxUnusedCachePages
requirement are retrieved before optimal-fit, decommitted entries.

This commit addresses the compiler errors raised
[here](https://github.com/llvm/llvm-project/pull/100818#issuecomment-2261043261).

* Suppress spurious warnings due to R_RISCV_SET_ULEB128

llvm-objdump -S issues unnecessary warnings for RISC-V relocatable files
containing .debug_loclists or .debug_rnglists sections with ULEB128
relocations. This occurred because `DWARFObjInMemory` verifies support for all
relocation types, triggering warnings for unsupported ones.

```
% llvm-objdump -S a.o
...
0000000000000000 <foo>:
warning: failed to compute relocation: R_RISCV_SUB_ULEB128, Invalid data was encountered while parsing the file
warning: failed to compute relocation: R_RISCV_SET_ULEB128, Invalid data was encountered while parsing the file
...
```

This change fixes #101544 by declaring support for the two ULEB128
relocation types, silencing the spurious warnings.

---

In DWARF v5 builds, DW_LLE_offset_pair/DW_RLE_offset_pair might be
generated in .debug_loclists/.debug_rnglists with ULEB128 relocations.
They are only read by llvm-dwarfdump to dump section content and verbose
DW_AT_location/DW_AT_ranges output for relocatable files.

The DebugInfoDWARF user (e.g. DWARFDebugRnglists.cpp) calls
`Data.getULEB128` without checking the ULEB128 relocations, as the
unrelocated value holds meaning (refer to the assembler
implementation https://reviews.llvm.org/D157657). This differs from
`.quad .Lfoo`, which requires relocation reading (e.g.
https://reviews.llvm.org/D74404).

Pull Request: https://github.com/llvm/llvm-project/pull/101607

* [GlobalIsel] Combine G_ADD and G_SUB with constants (#97771)

* [libc][newhdrgen]sorted function names in yaml (#102544)

* [NVPTX] support switch statement with brx.idx (reland) (#102550)

Add custom lowering for `BR_JT` DAG nodes to the `brx.idx` PTX
instruction ([PTX ISA 9.7.13.4. Control Flow Instructions: brx.idx]
(https://docs.nvidia.com/cuda/parallel-thread-execution/#control-flow-instructions-brx-idx)).
Depending on the heuristics in DAG selection, `switch` statements may
now be lowered using `brx.idx`.

Note: this fixes the previous issue in #102400 by adding the isBarrier
attribute to BRX_END

* [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (#102496)

Instead of expanding in RISCVExpandPseudoInsts, expand during
MachineInstr to MCInst lowering.

We weren't doing anything in expansion other than copying operands.

* [RISCV] Remove riscv-experimental-rv64-legal-i32. (#102509)

This has received no development work in a while and is slowly bit
rotting as new extensions are added.

At the moment, I don't think this is viable without adding a new
invariant that 32 bit values are always in sign extended form like
Mips64 does. We are very dependent on computeKnownBits and
ComputeNumSignBits in SelectionDAG to remove sign extends created for
ABI reasons. If we can't propagate sign bit information through 64-bit
values in SelectionDAG, we can't effectively clean up those extends.

* [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (#102416)

We already ended up with -fptrauth-returns, the feature macro, the lang
opt, and the actual backend lowering.

The only part left is threading it all through PointerAuthOptions, to
drive the addition of the "ptrauth-returns" attribute to generated
functions.
While there, do minor cleanup on ptrauth-function-attributes.c.

This also adds ptrauth_key_return_address to ptrauth.h.

* Return available function types for BindingDecls. (#102196)

Only return nullptr when we don't have an available QualType.

* [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC

* Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (#102086)"

This reverts commit 2fe61a5acf272d6826352ef72f47196b01003fc5.

* [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (#102651)

Follow on to #101232, as suggested in the comments, narrow the scope of
the preserved analyses.

* [clang] Implement -fptrauth-auth-traps. (#102417)

This provides -fptrauth-auth-traps, which at the frontend level only
controls the addition of the "ptrauth-auth-traps" function attribute.

The attribute in turn controls various aspects of backend codegen, by
providing the guarantee that every "auth" operation generated will trap
on failure.

This can either be delegated to the hardware (if AArch64 FPAC is known
to be available), in which case this attribute doesn't change codegen.
Otherwise, if FPAC isn't available, this asks the backend to emit
additional instructions to check and trap on auth failure.

* [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (#102665)

This updates some code to consistently use cpp::numeric_limits,
the src/__support polyfill for std::numeric_limits, rather than
the C <limits.h> macros.  This is in keeping with the general
C++-oriented style in libc code, and also sidesteps issues about
the new C23 *_WIDTH macros that the compiler-provided header does
not define outside C23 mode.

Bug: https://issues.fuchsia.dev/358196552

* [lldb] Move definition of SBSaveCoreOptions dtor out of header (#102539)

This class is technically not usable in its current state. When you use
it in a simple C++ project, your compiler will complain about an
incomplete definition of SaveCoreOptions. Normally this isn't a problem,
other classes in the SBAPI do this. The difference is that
SBSaveCoreOptions has a default destructor in the header, so the
compiler will attempt to generate the code for the destructor with an
incomplete definition of the impl type.

All methods for every class, including constructors and destructors,
must have a separate implementation not in a header.

* [mlir][ODS] Consistent `cppType` / `cppClassName` usage (#102657)

Make sure that the usage of `cppType` and `cppClassName` of type and
attribute definitions/constraints is consistent in TableGen.

- `cppClassName`: The C++ class name of the type or attribute.
- `cppType`: The fully qualified C++ class name: C++ namespace and C++
class name.

Basically, we should always use the fully qualified C++ class name for
parameter types, return types or template arguments.

Also some minor cleanups.

Fixes #57279.

* [LTO] enable `ObjCARCContractPass` only on optimized build  (#101114)

\#92331 tried to make `ObjCARCContractPass` by default, but it caused a
regression on O0 builds and was reverted.
This patch trys to bring that back by:

1. reverts the
[revert](https://github.com/llvm/llvm-project/commit/1579e9ca9ce17364963861517fecf13b00fe4d8a).
2. `createObjCARCContractPass` only on optimized builds.

Tests are updated to refelect the changes. Specifically, all `O0` tests
should not include `ObjCARCContractPass`

Signed-off-by: Peter Rong <[email protected]>

* [mlir][ODS] Verify type constraints in Types and Attributes (#102326)

When a type/attribute is defined in TableGen, a type constraint can be
used for parameters, but the type constraint verification was missing.

Example:
```
def TestTypeVerification : Test_Type<"TestTypeVerification"> {
  let parameters = (ins AnyTypeOf<[I16, I32]>:$param);
  // ...
}
```

No verification code was generated to ensure that `$param` is I16 or
I32.

When type constraints a present, a new method will generated for types
and attributes: `verifyInvariantsImpl`. (The naming is similar to op
verifiers.) The user-provided verifier is called `verify` (no change).
There is now a new entry point to type/attribute verification:
`verifyInvariants`. This function calls both `verifyInvariantsImpl` and
`verify`. If neither of those two verifications are present, the
`verifyInvariants` function is not generated.

When a type/attribute is not defined in TableGen, but a verifier is
needed, users can implement the `verifyInvariants` function. (This
function was previously called `verify`.)

Note for LLVM integration: If you have an attribute/type that is not
defined in TableGen (i.e., just C++), you have to rename the
verification function from `verify` to `verifyInvariants`. (Most
attributes/types have no verification, in which case there is nothing to
do.)

Depends on #102657.

* [libc] Fix use of cpp::numeric_limits<...>::digits (#102674)

The previous change replaced INT_WIDTH with
cpp::numberic_limits<int>::digits, but these don't have the same
value.  While INT_WIDTH == UINT_WIDTH, not so for ::digits, so
use cpp::numberic_limits<unsigned int>::digits et al instead for
the intended effects.

Bug: https://issues.fuchsia.dev/358196552

* [SandboxIR] Implement the InsertElementInst class (#102404)

Heavily based on work by @vporpo.

* [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (#102662)

In device context managed memory is not available so it makes no sense
to allocate the descriptor using it. Fall back to fir.alloca as it is
handled well in device code.
cuf.free is just dropped.

* [libc] Clean up remaining use of *_WIDTH macros in printf (#102679)

The previous change missed the second spot doing the same thing.

Bug: https://issues.fuchsia.dev/358196552

* [flang][cuda] Fix lib dependency

* [mlir][bazel] add missing td dependency in mlir-tblgen test

* [mlir] Add support for parsing nested PassPipelineOptions (#101118)

- Added a default parsing implementation to `PassOptions` to allow
`Option`/`ListOption` to wrap PassOption objects. This is helpful when
creating meta-pipelines (pass pipelines composed of pass pipelines).
- Updated `ListOption` printing to enable round-tripping the output of
`dump-pass-pipeline` back into `mlir-opt` for more complex structures.

* [NVPTX][NFC] Update tests to use bfloat type (#101493)

Intrinsics are defined with a bfloat type as of commit
250f2bb2c6a9c288faeb821585e9394697c561d8, not i16 and i32 storage types.
As such declarations are no longer needed once the correct types are
used.

* [mlir][bazel] remove extra blanks in mlir-tblgen test

* [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (#102406)

This patch introduces Tracker::emplaceIfTracking(), a wrapper of Tracker::track() that will conditionally create the change object if tracking is enabled.
This patch also removes the `Parent` member field of `IRChangeBase`.

* [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (#101765)

ASTContext::getIntWidth returns 1 if isBooleanType(), and falls back on
getTypeSize in the default case, which itself just returns the Width
from getTypeInfo's returned struct, so can be used in all cases here,
not just for _BitInt types.

* [UnitTests] Convert a test to use opaque pointers (#102668)

* [compiler-rt][NFC] Replace environment variable with %t (#102197)

Certain tests within the compiler-rt subproject encountered "command not
found" errors when using lit's internal shell, particularly when trying
to use the `DIR` environment variable. When checking with the command
`LIT_USE_INTERNAL_SHELL=1 ninja check-compiler-rt`, I encountered the
following error:
```
********************
Testing: 
FAIL: SanitizerCommon-ubsan-i386-Linux :: sanitizer_coverage_trace_pc_guard-init.cpp (146 of 9570)
******************** TEST 'SanitizerCommon-ubsan-i386-Linux :: sanitizer_coverage_trace_pc_guard-init.cpp' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 5
DIR=/usr/local/google/home/harinidonthula/llvm-project/build/runtimes/runtimes-bins/compiler-rt/test/sanitizer_common/ubsan-i386-Linux/Output/sanitizer_coverage_trace_pc_guard-init.cpp.tmp_workdir
# executed command: DIR=/usr/local/google/home/harinidonthula/llvm-project/build/runtimes/runtimes-bins/compiler-rt/test/sanitizer_common/ubsan-i386-Linux/Output/sanitizer_coverage_trace_pc_guard-init.cpp.tmp_workdir
# .---command stderr------------
# | 'DIR=/usr/local/google/home/harinidonthula/llvm-project/build/runtimes/runtimes-bins/compiler-rt/test/sanitizer_common/ubsan-i386-Linux/Output/sanitizer_coverage_trace_pc_guard-init.cpp.tmp_workdir': command not found
# `-----------------------------
# error: command failed with exit status: 127
```
In this patch, I resolved these issues by removing the use of the `DIR`
environment variable. Instead, the tests now directly utilize
`%t_workdir` for managing temporary directories. Additionally, I
simplified the tests by embedding the clang command arguments directly
into the test scripts, which avoids complications with environment
variable expansion under lit's internal shell.

This fix ensures that the tests run smoothly with lit's internal shell
and prevents the "command not found" errors, improving the reliability
of the test suite when executed in this environment.

fixes: #102395
[link to
RFC](https://discourse.llvm.org/t/rfc-enabling-the-lit-internal-shell-by-default/80179)

* [TargetLowering] Handle vector types in expandFixedPointMul (#102635)

In TargetLowering::expandFixedPointMul when expanding fixed point
multiplication, and when using a widened MUL as strategy for the
lowering, there was a bug resulting in assertion failures like this:
   Assertion `VT.isVector() == N1.getValueType().isVector() &&
   "SIGN_EXTEND result type type should be vector iff the operand "
   "type is vector!"' failed.

Problem was that we did not consider that VT could be a vector type
when setting up the WideVT. This patch should fix that bug.

* [libc] Fix CFP long double and add tests (#102660)

The previous patch removing the fenv requirement for str to float had an
error that got missed due to a lack of tests. This patch fixes the issue
and adds tests, as well as updating the existing tests.

* [libc]  Moved range_reduction_double ifdef statement (#102659)

Sin/cos/tan fuzzers were having issues with ONE_TWENTY_EIGHT_OVER_PI, so
the LIBC_TARGET_CPU_HAS_FMA ifdef statement got moved from the
sin/cos/tan .cpp files to the range_reduction_double_common.cpp file.

* [SandboxIR][NFC] Use Tracker.emplaceIfTracking()

This patch replaces some of the remaining uses of Tracker::track() to
Tracker::emplaceIfTracking().

* [nsan] Make #include more conventional

* [ThinLTO]Clean up 'import-assume-unique-local' flag. (#102424)

While manual compiles can specify full file paths and build automation
tools use full, unique paths in practice, it's not clear whether it's a
general good practice to enforce full paths (fail a build if relative
paths are used).

`NumDefs == 1` condition [1] should hold true for many internal-linkage
vtables as long as full paths are indeed used to salvage the marginal
performance when local-linkage vtables are imported due to indirect
reference.
https://github.com/llvm/llvm-project/pull/100448#discussion_r1692068402
has more details.

[1]
https://github.com/llvm/llvm-project/pull/100448/files#diff-e7cb370fee46f0f773f2b5429dfab36b75126d3909ae98ee87ff3d0e3f75c6e9R215

* [SandboxIR][NFC] SingleLLVMInstructionImpl class (#102687)

This patch introduces the SingleLLVMInstructionImpl class which
implements a couple of functions shared across all Instructions that map
to a single LLVM Instructions. This avoids code replication.

* [AMDGPU][Attributor] Add a pass parameter `closed-world` for AMDGPUAttributor pass (#101760)

* FIX: Remove unused private data member `HasWholeProgramVisibility` in `AMDGPU.h`

* AMDGPU/NewPM: Port SIAnnotateControlFlow to new pass manager (#102653)

Does not yet add it to the pass pipeline. Somehow it causes
2 tests to assert in SelectionDAG, in functions without any
control flow.

* AMDGPU/NewPM: Port AMDGPUAnnotateUniformValues to new pass manager (#102654)

* AMDGPU/NewPM: Port SILowerI1Copies to new pass manager (#102663)

* [nsan] GetShadowAddrFor: Use (const) void * to decrease the number of casts

* [msan] Use namespace qualifier. NFC

nsan will port msan_allocator.cpp and msan_thread.cpp. Clean up the two
files first.

* [llvm] Construct SmallVector with ArrayRef (NFC) (#102712)

Without this patch, the constructor arguments come from
SmallVectorImpl, not ArrayRef.  This patch switches them to ArrayRef
so that we can construct SmallVector with a single argument.

Note that LLVM Programmer’s Manual prefers ArrayRef to SmallVectorImpl
for flexibility.

* [AArch64] Construct SmallVector<SDValue> with ArrayRef (NFC) (#102713)

* [mlir] Use llvm::is_contained (NFC) (#102714)

* AMDGPU/NewPM: Initialize class member

After #102654

* [TargetLowering] Use APInt::isSubsetOf to simplify an expression. NFC

* [clang] Use llvm::is_contained (NFC) (#102720)

* [llvm-objdump,test] Fix source-interleave.ll when /proc/self/cwd is unavailable

e.g. on Mach-O

* [clang][Interp] Start implementing unions and changing the active member (#102723)

* [libc++] re-enable clang-tidy in the CI and fix any issues (#102658)

It looks like we've accidentally disabled clang-tidy in the CI. This
re-enables it and fixes the issues accumulated while it was disabled.

* [clang][Interp] Improve "in call to" call argument printing (#102735)

Always go through toAPValue() first and pretty-print that. In the
future, I think we could get rid of the individual toDiagnosticString()
implementations. This way we also get the correct printing for floats.

* [clang][Interp] Do not call dtors of union members (#102739)

* [clang][Interp] Handle nested unions (#102743)

* [Polly] Use separate DT/LI/SE for outlined subfn. NFC. (#102460)

DominatorTree, LoopInfo, and ScalarEvolution are function-level analyses
that expect to be called only on instructions and basic blocks of the
function they were original created for. When Polly outlined a parallel
loop body into a separate function, it reused the same analyses seemed
to work until new checks to be added in #101198.

This patch creates new analyses for the subfunctions. GenDT, GenLI, and
GenSE now refer to the analyses of the current region of code. Outside
of an outlined function, they refer to the same analysis as used for the
SCoP, but are substituted within an outlined function.

Additionally to the cross-function queries of DT/LI/SE, we must not
create SCEVs that refer to a mix of expressions for old and generated
values. Currently, SCEVs themselves do not "remember" which
ScalarEvolution analysis they were created for, but mixing them is just
as unexpected as using DT/LI across function boundaries. Hence
`SCEVLoopAddRecRewriter` was combined into `ScopExpander`.
`SCEVLoopAddRecRewriter` only replaced induction variables but left
SCEVUnknowns to reference the old function. `SCEVParameterRewriter`
would have done so but its job was effectively superseded by
`ScopExpander`, and now also `SCEVLoopAddRecRewriter`. Some issues
persist put marked with a FIXME in the code. Changing them would
possibly cause this patch to be not NFC anymore.

* [libc] Fix `scablnf16` using `float16` instead of `_Float16`

* [LLD][NFC] Don't use x64 import library for x86 target in safeseh-md tests. (#102736)

Use llvm-lib to generate input library instead of a binary blob.

* [LLD][NFC] Make InputFile::getMachineType const. (#102737)

* [mlir][vector] Use `DenseI64ArrayAttr` in vector.multi_reduction (#102637)

This prevents some unnecessary conversions to/from int64_t and
IntegerAttr.

* [clang][Interp] Only zero-init first union member (#102744)

Zero-initializing all of them accidentally left the last member active.
Only initialize the first one.

* [Clang][Sema][OpenMP] Allow `thread_limit` to accept multiple expressions (#102715)

* [clang][Interp] Ignore unnamed bitfields when zeroing records (#102749)

Including unions, where this is more important.

* [clang][Interp] Fix activating via indirect field initializers (#102753)

Pointer::activate() propagates up anyway, so that is handled. But we
need to call activate() in any case since the parent might not be a
union, but the activate() is still needed. Always call it and hope that
the InUnion flag takes care of the potential performance problems.

* [NFC] Fix TableGen include guards to match paths (#102746)

- Fix include guards for headers under utils/TableGen to match their
paths.

* [GISel] Handle more opcodes in constant_fold_binop (#102640)

Update the list of opcodes handled by the constant_fold_binop combine to
match the ones that are folded in CSEMIRBuilder::buildInstr.

* [Support] Assert that DomTree nodes share parent (#101198)

A dominance query of a block that is in a different function is
ill-defined, so assert that getNode() is only called for blocks that are
in the same function.

There are two cases, where this behavior did occur. LoopFuse didn't
explicitly do this, but didn't invalidate the SCEV block dispositions,
leaving dangling pointers to free'ed basic blocks behind, causing
use-after-free. We do, however, want to be able to dereference basic
blocks inside the dominator tree, so that we can refer to them by a
number stored inside the basic block.

* [Serialization] Fix a warning

This patch fixes:

  clang/lib/Serialization/ASTReader.cpp:11484:13: error: unused
  variable '_' [-Werror,-Wunused-variable]

* [Serialization] Use traditional for loops (NFC) (#102761)

The use of _ requires either:

- (void)_ and curly braces, or
- [[maybe_unused]].

For simple repetitions like these, we can use traditional for loops
for readable warning-free code.

* [clang][Interp] Handle union copy/move ctors (#102762)

They don't have a body and we need to implement them ourselves. Use the
Memcpy op to do that.

* [sanitizer,test] Restore -fno-sized-deallocation coverage

-fsized-deallocation was recently made the default for C++17 onwards
(#90373). While here, remove unneeded -faligned-allocation.

* [dfsan] Use namespace qualifier and internalize accidentally exported functions. NFC

* [Utils] Add new merge-release-pr.py script. (#101630)

This script helps the release managers merge backport PR's.

It does the following things:

* Validate the PR, checks approval, target branch and many other things.
* Rebases the PR
* Checkout the PR locally
* Pushes the PR to the release branch
* Deletes the local branch

I have found the script very helpful to merge the PR's.

* [DFAJumpThreading] Rewrite the way paths are enumerated (#96127)

I tried to add a limit to number of blocks visited in the paths()
function but even with a very high limit the transformation coverage was
being reduced.

After looking at the code it seemed that the function was trying to
create paths of the form
`SwitchBB...DeterminatorBB...SwitchPredecessor`. This is inefficient
because a lot of nodes in those paths (nodes before DeterminatorBB)
would be irrelevant to the optimization. We only care about paths of the
form `DeterminatorBB_Pred DeterminatorBB...SwitchBB`. This weeds out a
lot of visited nodes.

In this patch I have added a hard limit to the number of nodes visited
and changed the algorithm for path calculation. Primarily I am
traversing the use-def chain for the PHI nodes that define the state. If
we have a hole in the use-def chain (no immediate predecessors) then I
call the paths() function.

I also had to the change the select instruction unfolding code to insert
redundant one input PHIs to allow the use of the use-def chain in
calculating the paths.

The test suite coverage with this patch (including a limit on nodes
visited) is as follows:

    Geomean diff:
      dfa-jump-threading.NumTransforms: +13.4%
      dfa-jump-threading.NumCloned: +34.1%
      dfa-jump-threading.NumPaths: -80.7%

Compile time effect vs baseline (pass enabled by default) is mostly
positive:
https://llvm-compile-time-tracker.com/compare.php?from=ad8705fda25f64dcfeb6264ac4d6bac36bee91ab&to=5a3af6ce7e852f0736f706b4a8663efad5bce6ea&stat=instructions:u

Change-Id: I0fba9e0f8aa079706f633089a8ccd4ecf57547ed

* [dfsan] Use namespace qualifier. NFC

* [Clang][CodeGen] Fix bad codegen when building Clang with latest MSVC (#102681)

Before this PR, when using the latest MSVC `Microsoft (R) C/C++
Optimizing Compiler Version 19.40.33813 for x64` one of the Clang unit
test used to fail: `CodeGenObjC/gnustep2-direct-method.m`, see full
failure log:
[here](https://github.com/llvm/llvm-project/pull/100517#issuecomment-2266269490).

This PR temporarily shuffles around the code to make the MSVC inliner/
optimizer happy and avoid the bug.

MSVC bug report:
https://developercommunity.visualstudio.com/t/Bad-code-generation-when-building-LLVM-w/10719589?port=1025&fsid=e572244a-cde7-4d75-a73d-9b8cd94204dd

* [clang-format] Add BreakBinaryOperations configuration (#95013)

By default, clang-format packs binary operations, but it may be
desirable to have compound operations be on individual lines instead of
being packed.

This PR adds the option `BreakBinaryOperations` to break up large
compound binary operations to be on one line each.

This applies to all logical and arithmetic/bitwise binary operations

Maybe partially addresses #79487 ?
Closes #58014 
Closes #57280

* [clang-format] Fix a serious bug in `git clang-format -f` (#102629)

With the --force (or -f) option, git-clang-format wipes out input files
excluded by a .clang-format-ignore file if they have unstaged changes.

This patch adds a hidden clang-format option --list-ignored that lists
such excluded files for git-clang-format to filter out.

Fixes #102459.

* [llvm-exegesis][unittests] Also disable SubprocessMemoryTest on SPARC (#102755)

Three `llvm-exegesis` tests
```
  LLVM-Unit :: tools/llvm-exegesis/./LLVMExegesisTests/SubprocessMemoryTest/DefinitionFillsCompletely
  LLVM-Unit :: tools/llvm-exegesis/./LLVMExegesisTests/SubprocessMemoryTest/MultipleDefinitions
  LLVM-Unit :: tools/llvm-exegesis/./LLVMExegesisTests/SubprocessMemoryTest/OneDefinition
```
`FAIL` on Linux/sparc64 like
```
llvm/unittests/tools/llvm-exegesis/X86/SubprocessMemoryTest.cpp:68: Failure
Expected equality of these values:
  SharedMemoryMapping[I]
    Which is: '\0'
  ExpectedValue[I]
    Which is: '\xAA' (170)
```
It seems like this test only works on little-endian hosts: three
sub-tests are already disabled on powerpc and s390x (both big-endian),
and the fourth is additionally guarded against big-endian hosts (making
the other guards unnecessary).

However, since it's not been analyzed if this is really an endianess
issue, this patch disables the whole test on powerpc and s390x as before
adding sparc to the mix.

Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`.

* [Analysis] Use llvm::set_is_subset (NFC) (#102766)

* [LegalizeTypes] Use APInt::getLowBitsSet instead of getAllOnes+zext. NFC

* Revert "[Support] Assert that DomTree nodes share parent" (#102780)

Reverts llvm/llvm-project#101198

Breaks multiple bots:
https://lab.llvm.org/buildbot/#/builders/72/builds/2103
https://lab.llvm.org/buildbot/#/builders/164/builds/1909
https://lab.llvm.org/buildbot/#/builders/66/builds/2706

* Revert "[clang][Interp] Improve "in call to" call argument printing" (#102785)

Reverts llvm/llvm-project#102735

Breaks https://lab.llvm.org/buildbot/#/builders/52/builds/1496

* [RISCV] Add IR tests for bf16 vmerge and vmv.v.v. NFC (#102775)

* [InstCombine] Use llvm::set_is_subset (NFC) (#102778)

* [profgen][NFC] Pass parameter as const_ref

Pass `ProbeNode` parameter of `trackInlineesOptimizedAway` as const
reference.

Reviewers: wlei-llvm, WenleiHe

Reviewed By: WenleiHe

Pull Request: https://github.com/llvm/llvm-project/pull/102787

* [MC][profgen][NFC] Expand auto for MCDecodedPseudoProbe

Expand autos in select places in preparation to #102789.

Reviewers: dcci, maksfb, WenleiHe, rafaelauler, ayermolo, wlei-llvm

Reviewed By: WenleiHe, wlei-llvm

Pull Request: https://github.com/llvm/llvm-project/pull/102788

* [Target] Construct SmallVector<MachineMemOperand *> with ArrayRef (NFC) (#102779)

* [clang][Interp] Properly adjust instance pointer in virtual calls (#102800)

`getDeclPtr()` will not just return what we want, but in this case a
pointer to the `vu` local variable.

* [clang][Interp][NFC] Add a failing test case (#102801)

* [Docs] Update meetup contact mail address (#99321)

Arnaud is no longer active.

* [NFC][libclang/python] Fix code highlighting in release notes (#102807)

This corrects a release note introduced in #98745

* [VPlan] Move VPWidenLoadRecipe::execute to VPlanRecipes.cpp (NFC).

Move VPWidenLoadRecipe::execute to VPlanRecipes.cpp in line with
other ::execute implementations that don't depend on anything
defined in LoopVectorization.cpp

* AMDGPU: Try to add some more amdgpu-perf-hint tests (#102644)

This test has hardly any test coverage, and no IR tests. Add a few
more tests involving calls, and add some IR checks. This pass needs
a lot of work to improve the test coverage, and to actually use
the cost model instead of making up its own accounting scheme.

* NewPM/AMDGPU: Port AMDGPUPerfHintAnalysis to new pass manager (#102645)

This was much more difficult than I anticipated. The pass is
not in a good state, with poor test coverage. The legacy PM
does seem to be relying on maintaining the map state between
different SCCs, which seems bad. The pass is going out of its
way to avoid putting the attributes it introduces onto non-callee
functions. If it just added them, we could use them directly
instead of relying on the map, I would think.

The NewPM path uses a ModulePass; I'm not sure if we should be
using CGSCC here but there seems to be some missing infrastructure
to support backend defined ones.

* [CI][libclang] Add PR autolabeling for libclang (#102809)

This automatically adds the `clang:as-a-library` label on PRs for the C
and Python bindings and the libclang library

---------

Co-authored-by: Vlad Serebrennikov <[email protected]>

* [clang-tidy] Fix modernize-use-std-format lit test signature (#102759)

My fix for my original fix of issue #92896 in
666d224248707f373577b5b049b5b0229100006c modified the function signature
for fmt::sprintf to more accurately match the real implementation in
libfmt but failed to do the same for absl::StrFormat. The latter fix
applied equally well to absl::StrFormat so it's important that its test
verifies that the bug is fixed too.

* [LV] Collect profitable VFs in ::getBestVF. (NFCI)

Move collectig profitable VFs to ::getBestVF, in preparation for
retiring selectVectorizationFactor.

* [LV] Adjust test for #48188 to use AVX level closer to report.

Update AVX level for https://github.com/llvm/llvm-project/issues/48188
to be closer to the one used in the preproducer.

* [LV] Regenerate check lines in preparation for #99808.

Regenerate check lines for test to avoid unrelated changes in
https://github.com/llvm/llvm-project/pull/99808.

* [llvm] Construct SmallVector with ArrayRef (NFC) (#102799)

* [RFC][GlobalISel] InstructionSelect: Allow arbitrary instruction erasure (#97670)

See https://discourse.llvm.org/t/rfc-globalisel-instructionselect-allow-arbitrary-instruction-erasure

* [gn build] Port d2336fd75cc9

* [GlobalISel] Combiner: Install Observer into MachineFunction

The Combiner doesn't install the Observer into the MachineFunction.
This probably went unnoticed, because MachineFunction::getObserver() is
currently only used in constrainOperandRegClass(), but this might cause
issues down the line.

Pull Request: https://github.com/llvm/llvm-project/pull/102156

* [clang][Interp] Propagate InUnion flag to base classes (#102804)

* [GlobalISel] Don't remove from unfinalized GISelWorkList

Remove a hack from GISelWorkList caused by the Combiner removing
instructions from an unfinalized GISelWorkList during the DCE phase.
This is in preparation for larger changes to the WorkListMaintainer.

Pull Request: https://github.com/llvm/llvm-project/pull/102158

* [LLD][COFF] Validate import library machine type. (#102738)

* [LegalizeTypes][RISCV] Use SExtOrZExtPromotedOperands to promote operands for USUBSAT. (#102781)

It doesn't matter which extend we use to promote the operands. Use
whatever is the most efficient.

The custom handler for RISC-V was using SIGN_EXTEND when the Zbb
extension is enabled so we no longer need that.

* [nsan] Add NsanThread and clear static TLS shadow

On thread creation, asan/hwasan/msan/tsan unpoison the thread stack and
static TLS blocks in case the blocks reuse previously freed memory that
is possibly poisoned. glibc nptl/allocatestack.c allocates thread stack
using a hidden, non-interceptable function.

nsan is similar: the shadow types for the thread stack and static TLS
blocks should be set to unknown, otherwise if the static TLS blocks
reuse previous shadow memory, and `*p += x` instead of `*p = x` is used
for the first assignment, the mismatching user and shadow memory could
lead to false positives.

NsanThread is also needed by the next patch to use the sanitizer
allocator.

Pull Request: https://github.com/llvm/llvm-project/pull/102718

* Bump CI container clang version to 18.1.8 (#102803)

This patch bumps the CI container LLVM version to 18.1.8. This should've
been bumped a while ago, but I just noticed that it was out of date.
This also allows us to drop a patch that we manually had to add as it is
by default included in v18.

* [mlir][affine] Fix crash in mlir::affine::getForInductionVarOwner() (#102625)

This change fixes a crash when getOwner()->getParent() is a nullptr

* [LV] Support generating masks for switch terminators. (#99808)

Update createEdgeMask to created masks where the terminator in Src is a
switch. We need to handle 2 separate cases:

1. Dst is not the default desintation. Dst is reached if any of the
cases with destination == Dst are taken. Join the conditions for each
case where destination == Dst using a logical OR.
2. Dst is the default destination. Dst is reached if none of the cases
with destination != Dst are taken. Join the conditions for each case
where the destination is != Dst using a logical OR and negate it.

Edge masks are created for every destination of cases and/or 
default when requesting a mask where the source is a switch.

Fixes https://github.com/llvm/llvm-project/issues/48188.

PR: https://github.com/llvm/llvm-project/pull/99808

* Make msan_allocator.cpp more conventional. NFC

nsan will port msan_allocator.cpp.

* [msan] Remove unneeded nullness CHECK

The pointer will immediate be dereferenced.

* [lldb] Construct SmallVector with ArrayRef (NFC) (#102793)

* [LV] Handle SwitchInst in ::isPredicatedInst.

After f0df4fbd0c7b, isPredicatedInst needs to handle SwitchInst as well.
Handle it the same as BranchInst.

This fixes a crash in the newly added test and improves the results for
one of the existing tests in predicate-switch.ll

Should fix https://lab.llvm.org/buildbot/#/builders/113/builds/2099.

* [CMake] Followup to #102396 and restore old DynamicLibrary symbols behavior (#102671)

Followup to #102138 and #102396, restore more old behavior to fix
ppc64-aix bot.

* [NFC] Eliminate top-level "using namespace" from some headers. (#102751)

- Eliminate top-level "using namespace" from some headers.

* libc: Remove `extern "C"` from main declarations (#102825)

This is invalid in C++, and clang recently started warning on it as of
#101853

* Revert "libc: Remove `extern "C"` from main declarations" (#102827)

Reverts llvm/llvm-project#102825

* [rtsan] Make sure rtsan gets initialized on mac (#100188)

Intermittently on my mac I was getting the same nullptr crash in dlsym.

We need to make sure rtsan gets initialized on mac between when the
binary starts running, and the first intercepted function is called.
Until that point we should use the DlsymAllocator.

* [lldb] Silence warning

This fixes:
```
[6831/7617] Building CXX object
tools\lldb\source\Target\CMakeFiles\lldbTarget.dir\ThreadPlanSingleThreadTimeout.cpp.obj
C:\src\git\llvm-project\lldb\source\Target\ThreadPlanSingleThreadTimeout.cpp(66)
: warning C4715:
'lldb_private::ThreadPlanSingleThreadTimeout::StateToString': not all
control paths return a value
```

* [openmp][runtime] Silence warnings

This fixes several of those when building with MSVC on Windows:
```
[3625/7617] Building CXX object
projects\openmp\runtime\src\CMakeFiles\omp.dir\kmp_affinity.cpp.obj
C:\src\git\llvm-project\openmp\runtime\src\kmp_affinity.cpp(2637):
warning C4062: enumerator 'KMP_HW_UNKNOWN' in switch of enum 'kmp_hw_t'
is not handled
C:\src\git\llvm-project\openmp\runtime\src\kmp.h(628): note: see
declaration of 'kmp_hw_t'
```

* [compiler-rt] Silence warnings

This fixes a few of these warnings, when building with Clang ToT on
Windows:
```
[622/7618] Building CXX object
projects\compiler-rt\lib\sanitizer_common\CMakeFiles\RTSanitizerCommonSymbolizer.x86_64.dir\sanitizer_symbolizer_win.cpp.obj
C:\src\git\llvm-project\compiler-rt\lib\sanitizer_common\sanitizer_symbolizer_win.cpp(74,3):
warning: cast from 'FARPROC' (aka 'long long (*)()') to
'decltype(::StackWalk64) *' (aka 'int (*)(unsigned long, void *, void *,
_tagSTACKFRAME64 *, void *, int (*)(void *, unsigned long long, void *,
unsigned long, unsigned long *), void *(*)(void *, unsigned long long),
unsigned long long (*)(void *, unsigned long long), unsigned long long
(*)(void *, void *, _tagADDRESS64 *))') converts to incompatible
function type [-Wcast-function-type-mismatch]
```

This is similar to https://github.com/llvm/llvm-project/pull/97905

* [lldb] Silence warning

This fixes the following warning, when building with Clang ToT on
Windows:
```
[6668/7618] Building CXX object
tools\lldb\source\Plugins\Process\Windows\Common\CMakeFiles\lldbPluginProcessWindowsCommon.dir\TargetThreadWindows.cpp.obj
C:\src\git\llvm-project\lldb\source\Plugins\Process\Windows\Common\TargetThreadWindows.cpp(182,22):
warning: cast from 'FARPROC' (aka 'long long (*)()') to
'GetThreadDescriptionFunctionPtr' (aka 'long (*)(void *, wchar_t **)')
converts to incompatible function type [-Wcast-function-type-mismatch]
```

This is similar to: https://github.com/llvm/llvm-project/pull/97905

* [lldb] Fix dangling expression

This fixes the following:
```
[6603/7618] Building CXX object
tools\lldb\source\Plugins\ObjectFile\PECOFF\CMakeFiles\lldbPluginObjectFilePECOFF.dir\WindowsMiniDump.cpp.obj
C:\src\git\llvm-project\lldb\source\Plugins\ObjectFile\PECOFF\WindowsMiniDump.cpp(29,25):
warning: object backing the pointer will be destroyed at the end of the
full-expression [-Wdangling-gsl]
   29 |   const auto &outfile = core_options.GetOutputFile().value();
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
	 1 warning generated.
```

* [builtins] Rename sysauxv to getauxval to reflect the function called. NFCI (#102796)

* [mlir] Fix build after ec50f5828f25 (#101021)

This commit fixes what appears to be invalid C++ -- a lambda capturing a
variable before it is declared. The code compiles with GCC and Clang but
not MSVC.

* [LoopVectorize][X86][AMDLibm] Add Missing AMD LibM trig vector intrinsics (#101125)

Adding the following linked to their docs:
-
[amd_vrs16_acosf](https://github.com/amd/aocl-libm-ose/blob/9c0b67293ba01e509a6308247d82a8f1adfbbc67/scripts/libalm.def#L221)
-
[amd_vrd2_cosh](https://github.com/amd/aocl-libm-ose/blob/9c0b67293ba01e509a6308247d82a8f1adfbbc67/scripts/libalm.def#L124)
-
[amd_vrs16_tanhf](https://github.com/amd/aocl-libm-ose/blob/9c0b67293ba01e509a6308247d82a8f1adfbbc67/scripts/libalm.def#L224)

* [NFC] [C++20] [Modules] Adjust the implementation of wasDeclEmitted to make it more clear

The preivous implementation of wasDeclEmitted may be confusing that
why we need to filter the declaration not from modules. Now adjust the
implementations to avoid the problems.

* Revert "[CMake] Followup to #102396 and restore old DynamicLibrary symbols behavior (#102671)"

This reverts commit 32973b08d8cb02c213d96df453ff323470304645. This fix
doesn't fix the build failure as expected and making few other
configuration broken too.

* [Sanitizer] Make sanitizer passes idempotent (#99439)

This PR changes the sanitizer passes to be idempotent. 
When any sanitizer pass is run after it has already been run before,
double instrumentation is seen in the resulting IR. This happens because
there is no check in the pass, to verify if IR has been instrumented
before.

This PR checks if "nosanitize_*" module flag is already present and if
true, return early without running the pass again.

* [mlir][IR] Auto-generate element type verification for VectorType (#102449)

#102326 enables verification of type parameters that are type
constraints. The element type verification for `VectorType` (and maybe
other builtin types in the future) can now be auto-generated.

Also remove redundant error checking in the vector type parser: element
type and dimensions are already checked by the verifier (which is called
from `getChecked`).

Depends on #102326.

* [clang][Interp][NFC] Cleanup CheckActive()

Assert that the given pointer is in a union if it's not active and use a
range-based for loop to find the active field.

* [mlir][linalg] fix linalg.batch_reduce_matmul auto cast (#102585)

Fix the auto-cast of `linalg.batch_reduce_matmul` from `cast_to_T(A *
cast_to_T(B)) + C` to `cast_to_T(A) * cast_to_T(B) + C`

* [clang][Interp][NFC] Move ctor compilation to compileConstructor

In preparation for having a similar function for destructors.

* Revert "[NFC] [C++20] [Modules] Adjust the implementation of wasDeclEmitted to make it more clear"

This reverts commit 4399f2a5ef38df381c2b65052621131890194d59.
This fails with Modules/aarch64-sme-keywords.cppm

* Reapply "[AMDGPU] Always lower s/udiv64 by constant to MUL" (#101942)

Reland #100723, fixing the ARM issue at the cost of a small loss of optimization in `test/CodeGen/AMDGPU/fshr.ll`

Solves #100383

* [clang] Avoid triggering vtable instantiation for C++23 constexpr dtor (#102605)

In C++23 anything can be constexpr, including a dtor of a class whose
members and bases don't have constexpr dtors. Avoid early triggering of
vtable instantiation int this case.

Fixes https://github.com/llvm/llvm-project/issues/102293

* [CMake] Don't pass -DBUILD_EXAMPLES to the build (#102838)

The only use in `opt.cpp` was removed in
d291f1fd094538af705541045c0d9c3ceb85e71d.

* [DataLayout] Move `operator=` to cpp file (NFC) (#102849)

`DataLayout` isn't exactly cheap to copy (448 bytes on a 64-bit host).
Move `operator=` to cpp file to improve compilation time. Also move
`operator==` closer to `operator=` and add a couple of FIXMEs.

* [GlobalISel] Fix implementation of CheckNumOperandsLE/GE

The condition was backwards - it was rejecting when the condition was met.

Fixes #102719

* [VPlan] Mark VPVectorPointer as only using the first part of the ptr.

VPVectorPointerRecipe only uses the first part of the pointer operand,
so mark it accordingly.

Follow-up suggested as part of
https://github.com/llvm/llvm-project/pull/99808.

* [mlir][Transforms] Add missing check in tosa::transpose::verify() (#102099)

The tosa::transpose::verify() should make sure
that the permutation numbers are within the size of 
the input array. Otherwise it will cause a cryptic array
out of bound assertion later.Fix #99513.

* [AMDGPU] add missing checks in processBaseWithConstOffset (#102310)

fixes https://github.com/llvm/llvm-project/issues/102231 by inserting
missing checks.

* [InstCombine] Don't change fn signature for calls to declarations (#102596)

transformConstExprCastCall() implements a number of highly dubious
transforms attempting to make a call function type line up with the
function type of the called function. Historically, the main value this
had was to avoid function type mismatches due to pointer type
differences, which is no longer relevant with opaque pointers.

This patch is a step towards reducing the scope of the transform, by
applying it only to definitions, not declarations. For declarations, the
declared signature might not match the actual function signature, e.g.
`void @fn()` is sometimes used as a placeholder for functions with
unknown signature. The implementation already bailed out in some cases
for declarations, but I think it would be safer to disable the transform
entirely.

For the test cases, I've updated some of them to use definitions
instead, so that the test coverage is preserved.

* [llvm][llvm-readobj] Add NT_ARM_FPMR corefile note type (#102594)

This contains the fpmr register which was added in Armv9.5-a. This
register mainly contains controls for fp8 formats.

It was added to the Linux Kernel in

https://github.com/torvalds/linux/commit/4035c22ef7d43a6c00d6a6584c60e902b95b46af.

* [analyzer][NFC] Trivial refactoring of region invalidation (#102456)

This commit removes `invalidateRegionsImpl()`, moving its body to
`invalidateRegions(ValueList Values, ...)`, because it was a completely
useless layer of indirection.

Moreover I'm fixing some strange indentation within this function body
and renaming two variables to the proper `UpperCamelCase` format.

* [VPlan] Replace hard-coded value number in test with pattern.

Make test more robust w.r.t. future changes.

* [NFC][Clang] clang-format a function declaration

* [dwarf2yaml] Correctly emit type and split unit headers (#102471)

(DWARFv5) split units have an extra `dwo_id` field in the header. Type
units have `type_signature` and `type_offset`.

* [LV] Only OR unique edges when creating block-in masks.

This removes redundant ORs of matching masks.

Follow-up to f0df4fbd0c7b to reduce the number of redundant ORs for
masks.

* [KnownBits] Add KnownBits::add and KnownBits::sub helper wrappers. (#99468)

* [clang][analyzer] Remove array bounds check from PointerSubChecker (#102580)

At pointer subtraction only pointers are allowed that point into an
array (or one after the end), this fact was checker by the checker. This
check is now removed because it is a special case of array indexing
error that is handled by different checkers (like ArrayBoundsV2).

* [lldb] Tolerate multiple compile units with the same DWO ID (#100577)

I ran into this when LTO completely emptied two compile units, so they
ended up with the same hash (see #100375). Although, ideally, the
compiler would try to ensure we don't end up with a hash col…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants