https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/176590

>From c01243bcbc79068bce0a3f7ad5a3779d53ea97c1 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Sat, 17 Jan 2026 16:46:46 +0530
Subject: [PATCH 1/4] [clang][bytecode] Fix stack corruption in pointer
 arithmetic discard

In VisitPointerArithBinOp, the result of pointer addition or subtraction
was always left on the stack, even if the result was intended to be
discarded (e.g. in a comma expression). This led to stack corruption
where subsequent operations would find an unexpected pointer on the
stack, causing an assertion failure in the InterpStack.

This patch ensures that we correctly respect the DiscardResult flag
for pointer arithmetic operations.

Fixes #176549
---
 clang/lib/AST/ByteCode/Compiler.cpp  | 20 +++++++++++---------
 clang/test/AST/ByteCode/gh176549.cpp |  8 ++++++++
 2 files changed, 19 insertions(+), 9 deletions(-)
 create mode 100644 clang/test/AST/ByteCode/gh176549.cpp

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 21f8db06919ed..66b0cc4b5f6ab 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1083,20 +1083,22 @@ bool Compiler<Emitter>::VisitPointerArithBinOp(const 
BinaryOperator *E) {
   if (Op == BO_Add) {
     if (!this->emitAddOffset(OffsetType, E))
       return false;
-
-    if (classifyPrim(E) != PT_Ptr)
-      return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
-    return true;
-  }
-  if (Op == BO_Sub) {
+  } else if (Op == BO_Sub) {
     if (!this->emitSubOffset(OffsetType, E))
       return false;
+  } else {
+    return false;
+  }
 
-    if (classifyPrim(E) != PT_Ptr)
-      return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
-    return true;
+  if (classifyPrim(E) != PT_Ptr) {
+    if (!this->emitDecayPtr(PT_Ptr, classifyPrim(E), E))
+      return false;
   }
 
+  if (DiscardResult)
+    return this->emitPop(classifyPrim(E), E);
+  return true;
+
   return false;
 }
 
diff --git a/clang/test/AST/ByteCode/gh176549.cpp 
b/clang/test/AST/ByteCode/gh176549.cpp
new file mode 100644
index 0000000000000..b56f762b7ede4
--- /dev/null
+++ b/clang/test/AST/ByteCode/gh176549.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+// expected-no-diagnostics
+
+const char a[4] = "abc";
+void foo() {
+  int i = 0;
+  i = 1 > (a + 1, sizeof(a));
+}

>From 59f33d9ed24e822f84283fa84fd72e6b25b440d2 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Sun, 18 Jan 2026 00:34:45 +0530
Subject: [PATCH 2/4] [AMDGPU] Fix assertion failure in SIPreEmitPeephole

Fixes #176578. Add check for register operand before calling getReg() in 
optimizeVccBranch to prevent assertion failure when operand is an immediate.
---
 llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp 
b/llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp
index 8785968569d92..d15f89fdc78fc 100644
--- a/llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp
+++ b/llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp
@@ -153,11 +153,12 @@ bool SIPreEmitPeephole::optimizeVccBranch(MachineInstr 
&MI) const {
 
   MachineOperand &Op1 = A->getOperand(1);
   MachineOperand &Op2 = A->getOperand(2);
-  if (Op1.getReg() != ExecReg && Op2.isReg() && Op2.getReg() == ExecReg) {
+  if ((!Op1.isReg() || Op1.getReg() != ExecReg) && Op2.isReg() &&
+      Op2.getReg() == ExecReg) {
     TII->commuteInstruction(*A);
     Changed = true;
   }
-  if (Op1.getReg() != ExecReg)
+  if (!Op1.isReg() || Op1.getReg() != ExecReg)
     return Changed;
   if (Op2.isImm() && !(Op2.getImm() == -1 || Op2.getImm() == 0))
     return Changed;

>From 1b42936a2ee9b9a88279a4b718897167bfa14235 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Sun, 18 Jan 2026 00:35:08 +0530
Subject: [PATCH 3/4] [InstCombine] Fix compilation error in m_LogicalOp usages

Replace incorrect 3-argument m_LogicalOp matcher with explicit 
m_LogicalAnd/m_LogicalOr matchers.
---
 .../InstCombine/InstCombineAndOrXor.cpp       | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index aacb2e2a91c57..80a7f0de363f0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3612,6 +3612,48 @@ Value *InstCombinerImpl::foldBooleanAndOr(Value *LHS, 
Value *RHS,
   if (Value *Res = foldEqOfParts(LHS, RHS, IsAnd))
     return Res;
 
+  // Handle reassociation-like folding: (A op B) op C --> A op (B op C)
+  // where B and C are ICmps and can be folded.
+  // This handles patterns like:
+  //   select (and %cond, icmp1), icmp2, false -> select %cond, folded_icmp, 
false
+  //   (A & icmp1) & icmp2 -> A & folded_icmp
+  auto TryFold = [&](Value *L, Value *R) -> Value * {
+    Value *A, *B;
+    Instruction::BinaryOps Opcode = IsAnd ? Instruction::And : Instruction::Or;
+
+    // Look through (Op A, B)
+    if (match(L, m_BinOp(Opcode, m_Value(A), m_Value(B))) ||
+        (IsLogical && (IsAnd ? match(L, m_LogicalAnd(m_Value(A), m_Value(B)))
+                             : match(L, m_LogicalOr(m_Value(A), 
m_Value(B)))))) {
+      for (int i = 0; i < 2; ++i) {
+        Value *InnerCmp = i == 0 ? B : A;
+        Value *Other = i == 0 ? A : B;
+        auto *ICmpInner = dyn_cast<ICmpInst>(InnerCmp);
+        auto *ICmpR = dyn_cast<ICmpInst>(R);
+        if (ICmpInner && ICmpR) {
+          if (Value *Res = foldAndOrOfICmps(ICmpInner, ICmpR, I, IsAnd, 
IsLogical)) {
+            if (IsLogical) {
+              if (IsAnd)
+                return Builder.CreateSelect(Other, Res,
+                                            
ConstantInt::getFalse(LHS->getType()));
+              else
+                return Builder.CreateSelect(Other, 
ConstantInt::getTrue(LHS->getType()),
+                                            Res);
+            } else {
+              return Builder.CreateBinOp(Opcode, Other, Res);
+            }
+          }
+        }
+      }
+    }
+    return nullptr;
+  };
+
+  if (Value *V = TryFold(LHS, RHS))
+    return V;
+  if (Value *V = TryFold(RHS, LHS))
+    return V;
+
   return nullptr;
 }
 

>From fd90726fef7d5ec2e29130948acdccc358938156 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Sun, 18 Jan 2026 14:28:27 +0530
Subject: [PATCH 4/4] [clang][bytecode] Fix crash in void functions returning
 non-void expr

- Move test case to functions.cpp
- Use RE->containsErrors() check as suggested by review
---
 clang/lib/AST/ByteCode/Compiler.cpp   | 5 ++++-
 clang/test/AST/ByteCode/functions.cpp | 7 +++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 66b0cc4b5f6ab..36d6f3f91e237 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5680,7 +5680,10 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt 
*RS) {
       return this->emitRet(*ReturnType, RS);
     }
 
-    if (RE->getType()->isVoidType()) {
+    if (RE->containsErrors()) {
+      if (!this->discard(RE))
+        return false;
+    } else if (RE->getType()->isVoidType()) {
       if (!this->visit(RE))
         return false;
     } else {
diff --git a/clang/test/AST/ByteCode/functions.cpp 
b/clang/test/AST/ByteCode/functions.cpp
index 21d3ddaafaee3..a094767d04503 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -735,3 +735,10 @@ namespace PtrPtrCast {
   void foo() { ; }
   void bar(int *a) { a = (int *)(void *)(foo); }
 }
+
+namespace GH176536 {
+  constexpr void foo(int n) {
+    return n > 1 ? foo(n - 1) : 0; // both-error {{return type 'void' must 
match the return type 'int' of the expression}}
+  }
+  static_assert((foo(2), true), "");
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to