[llvm] bff34a0 - [AArch64] Only enable `foldCSELOfCSEl` DAG combine when x != y

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 10 18:46:15 PST 2023


Author: chenglin.bi
Date: 2023-01-11T10:46:09+08:00
New Revision: bff34a0a5f9b757ee99bf04f1e4c547bfd33e8f5

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

LOG: [AArch64] Only enable `foldCSELOfCSEl` DAG combine when x != y

https://alive2.llvm.org/ce/z/Uy_x_b

Fix: https://github.com/llvm/llvm-project/issues/59902

Reviewed By: dmgreen

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

Added: 
    llvm/test/CodeGen/AArch64/pr59902.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 26f185350f35..179eedc564f0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -20023,11 +20023,11 @@ static SDValue foldCSELofCTTZ(SDNode *N, SelectionDAG &DAG) {
 
 // (CSEL l r EQ (CMP (CSEL x y cc2 cond) x)) => (CSEL l r cc2 cond)
 // (CSEL l r EQ (CMP (CSEL x y cc2 cond) y)) => (CSEL l r !cc2 cond)
-// Where x and y are constants
+// Where x and y are constants and x != y
 
 // (CSEL l r NE (CMP (CSEL x y cc2 cond) x)) => (CSEL l r !cc2 cond)
 // (CSEL l r NE (CMP (CSEL x y cc2 cond) y)) => (CSEL l r cc2 cond)
-// Where x and y are constants
+// Where x and y are constants and x != y
 static SDValue foldCSELOfCSEL(SDNode *Op, SelectionDAG &DAG) {
   SDValue L = Op->getOperand(0);
   SDValue R = Op->getOperand(1);
@@ -20048,10 +20048,18 @@ static SDValue foldCSELOfCSEL(SDNode *Op, SelectionDAG &DAG) {
 
   SDValue X = CmpLHS->getOperand(0);
   SDValue Y = CmpLHS->getOperand(1);
-  if (!isa<ConstantSDNode>(X) || !isa<ConstantSDNode>(Y)) {
+  if (!isa<ConstantSDNode>(X) || !isa<ConstantSDNode>(Y) || X == Y) {
     return SDValue();
   }
 
+  // If one of the constant is opaque constant, x,y sdnode is still 
diff erent
+  // but the real value maybe the same. So check APInt here to make sure the
+  // code is correct.
+  ConstantSDNode *CX = cast<ConstantSDNode>(X);
+  ConstantSDNode *CY = cast<ConstantSDNode>(Y);
+  if (CX->getAPIntValue() == CY->getAPIntValue())
+    return SDValue();
+
   AArch64CC::CondCode CC =
       static_cast<AArch64CC::CondCode>(CmpLHS->getConstantOperandVal(2));
   SDValue Cond = CmpLHS->getOperand(3);

diff  --git a/llvm/test/CodeGen/AArch64/pr59902.ll b/llvm/test/CodeGen/AArch64/pr59902.ll
new file mode 100644
index 000000000000..9e07e5f271cb
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/pr59902.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
+
+; This used to miscompile because foldCSELOfCSEL function
+; doesn't check const x != y
+define i1 @test() {
+; CHECK-LABEL: test:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x8, #9007199254740990
+; CHECK-NEXT:    movk x8, #65503, lsl #16
+; CHECK-NEXT:    movk x8, #65407, lsl #32
+; CHECK-NEXT:    cmp x8, x8
+; CHECK-NEXT:    csel x9, x8, x8, gt
+; CHECK-NEXT:    cmp x9, x8
+; CHECK-NEXT:    cset w0, eq
+; CHECK-NEXT:    ret
+  %1 = select i1 false, i64 0, i64 9006649496829950
+  %2 = call i64 @llvm.smax.i64(i64 %1, i64 9006649496829950)
+  %3 = icmp eq i64 %2, 9006649496829950
+  ret i1 %3
+}
+
+declare i64 @llvm.smax.i64(i64, i64)


        


More information about the llvm-commits mailing list