[llvm] [TargetLowering] zextOrTrunc for xor and or if top bits are known 0, just like AND (PR #146079)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 27 07:10:52 PDT 2025


https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/146079

None

>From 7a7543eaac4b393ef13ef3713dcf43388b70e829 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Fri, 27 Jun 2025 09:31:43 -0400
Subject: [PATCH] [TargetLowering] zextOrTrunc for xor and or if top bits are
 known 0, just like AND

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 27 +++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 000f8cc6786a5..62faf3cb1d8c8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -4240,14 +4240,26 @@ SDValue TargetLowering::foldSetCCWithOr(EVT VT, SDValue N0, SDValue N1,
 
   SelectionDAG &DAG = DCI.DAG;
   EVT OpVT = N0.getValueType();
-  if (!N0.hasOneUse() || !OpVT.isInteger() ||
+  if (N0.getOpcode() != ISD::OR || !OpVT.isInteger() ||
       (Cond != ISD::SETEQ && Cond != ISD::SETNE))
     return SDValue();
 
+  // (X | Y) != 0 --> zextOrTrunc(X | Y)
+  // iff everything but LSB is known zero:
+  if (Cond == ISD::SETNE && isNullConstant(N1) &&
+      (getBooleanContents(OpVT) == TargetLowering::UndefinedBooleanContent ||
+       getBooleanContents(OpVT) == TargetLowering::ZeroOrOneBooleanContent)) {
+    unsigned NumEltBits = OpVT.getScalarSizeInBits();
+    APInt UpperBits = APInt::getHighBitsSet(NumEltBits, NumEltBits - 1);
+    if (DAG.MaskedValueIsZero(N0, UpperBits))
+      return DAG.getBoolExtOrTrunc(N0, DL, VT, OpVT);
+  }
+
   // (X | Y) == Y
   // (X | Y) != Y
   SDValue X;
-  if (sd_match(N0, m_Or(m_Value(X), m_Specific(N1))) && hasAndNotCompare(N1)) {
+  if (N0.hasOneUse() && sd_match(N0, m_Or(m_Value(X), m_Specific(N1))) &&
+      hasAndNotCompare(N1)) {
     // If the target supports an 'and-not' or 'and-complement' logic operation,
     // try to use that to make a comparison operation more efficient.
 
@@ -4447,6 +4459,17 @@ SDValue TargetLowering::foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1,
   if (X == N1)
     return DAG.getSetCC(DL, VT, Y, DAG.getConstant(0, DL, OpVT), Cond);
 
+  // (X ^ Y) != 0 --> zextOrTrunc(X ^ Y)
+  // iff everything but LSB is known zero:
+  if (BOpcode == ISD::XOR && Cond == ISD::SETNE && isNullConstant(N1) &&
+      (getBooleanContents(OpVT) == TargetLowering::UndefinedBooleanContent ||
+       getBooleanContents(OpVT) == TargetLowering::ZeroOrOneBooleanContent)) {
+    unsigned NumEltBits = OpVT.getScalarSizeInBits();
+    APInt UpperBits = APInt::getHighBitsSet(NumEltBits, NumEltBits - 1);
+    if (DAG.MaskedValueIsZero(N0, UpperBits))
+      return DAG.getBoolExtOrTrunc(N0, DL, VT, OpVT);
+  }
+
   if (Y != N1)
     return SDValue();
 



More information about the llvm-commits mailing list