[llvm] a04b532 - [LegalizeIntegerTypes][RISCV] Teach PromoteSetCCOperands to check sign bits of unsigned compares.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 4 12:39:07 PST 2022


Author: Craig Topper
Date: 2022-01-04T12:38:47-08:00
New Revision: a04b5325051c906a8a0ddc58fffa1b095e024314

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

LOG: [LegalizeIntegerTypes][RISCV] Teach PromoteSetCCOperands to check sign bits of unsigned compares.

Unsigned compares work with either zero extended or sign extended
inputs just like equality comparisons. I didn't allow this when
I refactored the code in D116421 due to lack of tests. But I've
since found a simple C test case that demonstrates when this can be
useful.

Reviewed By: efriedma

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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/test/CodeGen/RISCV/alu16.ll
    llvm/test/CodeGen/RISCV/alu8.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 32086a79acdf6..4a1e9d89df682 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1747,18 +1747,16 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &LHS, SDValue &RHS,
 
   // Prefer to promote the comparison operand with zero extension.
 
-  // If this is an equality comparison and the width of OpL/OpR excluding the
-  // duplicated sign bits is no greater than the width of LHS/RHS, we can avoid
-  // inserting a zext_inreg operation that we might not be able to remove.
-  if (ISD::isIntEqualitySetCC(CCCode)) {
-    unsigned OpLEffectiveBits = DAG.ComputeMaxSignificantBits(OpL);
-    unsigned OpREffectiveBits = DAG.ComputeMaxSignificantBits(OpR);
-    if (OpLEffectiveBits <= LHS.getScalarValueSizeInBits() &&
-        OpREffectiveBits <= RHS.getScalarValueSizeInBits()) {
-      LHS = OpL;
-      RHS = OpR;
-      return;
-    }
+  // If the width of OpL/OpR excluding the duplicated sign bits is no greater
+  // than the width of LHS/RHS, we can avoid/ inserting a zext_inreg operation
+  // that we might not be able to remove.
+  unsigned OpLEffectiveBits = DAG.ComputeMaxSignificantBits(OpL);
+  unsigned OpREffectiveBits = DAG.ComputeMaxSignificantBits(OpR);
+  if (OpLEffectiveBits <= LHS.getScalarValueSizeInBits() &&
+      OpREffectiveBits <= RHS.getScalarValueSizeInBits()) {
+    LHS = OpL;
+    RHS = OpR;
+    return;
   }
 
   // Otherwise, use zext_inreg.

diff  --git a/llvm/test/CodeGen/RISCV/alu16.ll b/llvm/test/CodeGen/RISCV/alu16.ll
index 23dc433baf4ea..b1f5e4a9aa852 100644
--- a/llvm/test/CodeGen/RISCV/alu16.ll
+++ b/llvm/test/CodeGen/RISCV/alu16.ll
@@ -62,6 +62,24 @@ define i16 @sltiu(i16 %a) nounwind {
   ret i16 %2
 }
 
+; Make sure we avoid an AND, if the input of an unsigned compare is known
+; to be sign extended. This can occur due to InstCombine canonicalizing
+; x s>= 0 && x s< 10 to x u< 10.
+define i16 @sltiu_signext(i16 signext %a) nounwind {
+; RV32I-LABEL: sltiu_signext:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    sltiu a0, a0, 10
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: sltiu_signext:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    sltiu a0, a0, 10
+; RV64I-NEXT:    ret
+  %1 = icmp ult i16 %a, 10
+  %2 = zext i1 %1 to i16
+  ret i16 %2
+}
+
 define i16 @xori(i16 %a) nounwind {
 ; RV32I-LABEL: xori:
 ; RV32I:       # %bb.0:

diff  --git a/llvm/test/CodeGen/RISCV/alu8.ll b/llvm/test/CodeGen/RISCV/alu8.ll
index ed09174745b88..8611e752028d4 100644
--- a/llvm/test/CodeGen/RISCV/alu8.ll
+++ b/llvm/test/CodeGen/RISCV/alu8.ll
@@ -58,6 +58,24 @@ define i8 @sltiu(i8 %a) nounwind {
   ret i8 %2
 }
 
+; Make sure we avoid an AND, if the input of an unsigned compare is known
+; to be sign extended. This can occur due to InstCombine canonicalizing
+; x s>= 0 && x s< 10 to x u< 10.
+define i8 @sltiu_signext(i8 signext %a) nounwind {
+; RV32I-LABEL: sltiu_signext:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    sltiu a0, a0, 10
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: sltiu_signext:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    sltiu a0, a0, 10
+; RV64I-NEXT:    ret
+  %1 = icmp ult i8 %a, 10
+  %2 = zext i1 %1 to i8
+  ret i8 %2
+}
+
 define i8 @xori(i8 %a) nounwind {
 ; RV32I-LABEL: xori:
 ; RV32I:       # %bb.0:


        


More information about the llvm-commits mailing list