[llvm] e11420c - [ARM] Ensure CSINC has one use in CSINV combine

David Green via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 29 02:59:27 PDT 2021


Author: David Green
Date: 2021-04-29T10:59:14+01:00
New Revision: e11420ca2371cb8e53fec90cfc619ddf8249c965

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

LOG: [ARM] Ensure CSINC has one use in CSINV combine

Otherwise the CMP glue may be used in multiple nodes, needing to be
emitted multiple times. Currently this either increases instruction
count or fails as it attempt to insert the same node multiple times.

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/test/CodeGen/Thumb2/csel.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 24dded2c5cd2..1ea4cb4ed602 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -12766,7 +12766,7 @@ static SDValue PerformSubCSINCCombine(SDNode *N,
   if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
     return SDValue();
   SDValue CSINC = N->getOperand(1);
-  if (CSINC.getOpcode() != ARMISD::CSINC)
+  if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
     return SDValue();
 
   ConstantSDNode *X = dyn_cast<ConstantSDNode>(CSINC.getOperand(0));

diff  --git a/llvm/test/CodeGen/Thumb2/csel.ll b/llvm/test/CodeGen/Thumb2/csel.ll
index 5a56fb6f692d..137aef32a437 100644
--- a/llvm/test/CodeGen/Thumb2/csel.ll
+++ b/llvm/test/CodeGen/Thumb2/csel.ll
@@ -336,3 +336,31 @@ entry:
   ret i32 %xor
 }
 
+define i32 @csinc_to_csinv(i32 %a) {
+; CHECK-LABEL: csinc_to_csinv:
+; CHECK:       @ %bb.0: @ %entry
+; CHECK-NEXT:    cmp r0, #46
+; CHECK-NEXT:    csetm r0, lt
+; CHECK-NEXT:    bx lr
+entry:
+  %cmp = icmp sgt i32 %a, 45
+  %spec.select = select i1 %cmp, i32 0, i32 1
+  %s = sub i32 0, %spec.select
+  ret i32 %s
+}
+
+define i32 @csinc_to_csinv_multi(i32 %a) {
+; CHECK-LABEL: csinc_to_csinv_multi:
+; CHECK:       @ %bb.0: @ %entry
+; CHECK-NEXT:    cmp r0, #46
+; CHECK-NEXT:    cset r0, lt
+; CHECK-NEXT:    rsbs r1, r0, #0
+; CHECK-NEXT:    eors r0, r1
+; CHECK-NEXT:    bx lr
+entry:
+  %cmp = icmp sgt i32 %a, 45
+  %spec.select = select i1 %cmp, i32 0, i32 1
+  %s = sub i32 0, %spec.select
+  %t = xor i32 %s, %spec.select
+  ret i32 %t
+}


        


More information about the llvm-commits mailing list