[CVP] Handle use-site conditions in more folds
authorNikita Popov <npopov@redhat.com>
Tue, 17 Jan 2023 15:10:41 +0000 (16:10 +0100)
committerNikita Popov <npopov@redhat.com>
Tue, 17 Jan 2023 15:14:55 +0000 (16:14 +0100)
llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll

index c0d1098..24d8ccb 100644 (file)
@@ -733,7 +733,7 @@ static bool narrowSDivOrSRem(BinaryOperator *Instr, LazyValueInfo *LVI) {
   std::array<std::optional<ConstantRange>, 2> CRs;
   unsigned MinSignedBits = 0;
   for (auto I : zip(Instr->operands(), CRs)) {
-    std::get<1>(I) = LVI->getConstantRange(std::get<0>(I), Instr);
+    std::get<1>(I) = LVI->getConstantRangeAtUse(std::get<0>(I));
     MinSignedBits = std::max(std::get<1>(I)->getMinSignedBits(), MinSignedBits);
   }
 
@@ -844,8 +844,8 @@ static bool narrowUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) {
   // What is the smallest bit width that can accommodate the entire value ranges
   // of both of the operands?
   unsigned MaxActiveBits = 0;
-  for (Value *Operand : Instr->operands()) {
-    ConstantRange CR = LVI->getConstantRange(Operand, Instr);
+  for (const Use &U : Instr->operands()) {
+    ConstantRange CR = LVI->getConstantRangeAtUse(U);
     MaxActiveBits = std::max(CR.getActiveBits(), MaxActiveBits);
   }
   // Don't shrink below 8 bits wide.
@@ -891,8 +891,8 @@ static bool processSRem(BinaryOperator *SDI, LazyValueInfo *LVI) {
   if (SDI->getType()->isVectorTy())
     return false;
 
-  ConstantRange LCR = LVI->getConstantRange(SDI->getOperand(0), SDI);
-  ConstantRange RCR = LVI->getConstantRange(SDI->getOperand(1), SDI);
+  ConstantRange LCR = LVI->getConstantRangeAtUse(SDI->getOperandUse(0));
+  ConstantRange RCR = LVI->getConstantRangeAtUse(SDI->getOperandUse(1));
 
   if (LCR.abs().icmp(CmpInst::ICMP_ULT, RCR.abs())) {
     SDI->replaceAllUsesWith(SDI->getOperand(0));
@@ -1026,7 +1026,7 @@ static bool processAShr(BinaryOperator *SDI, LazyValueInfo *LVI) {
   if (SDI->getType()->isVectorTy())
     return false;
 
-  ConstantRange LRange = LVI->getConstantRange(SDI->getOperand(0), SDI);
+  ConstantRange LRange = LVI->getConstantRangeAtUse(SDI->getOperandUse(0));
   unsigned OrigWidth = SDI->getType()->getIntegerBitWidth();
   ConstantRange NegOneOrZero =
       ConstantRange(APInt(OrigWidth, (uint64_t)-1, true), APInt(OrigWidth, 1));
@@ -1116,7 +1116,7 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
 
   // Pattern match (and lhs, C) where C includes a superset of bits which might
   // be set in lhs.  This is a common truncation idiom created by instcombine.
-  Value *LHS = BinOp->getOperand(0);
+  const Use &LHS = BinOp->getOperandUse(0);
   ConstantInt *RHS = dyn_cast<ConstantInt>(BinOp->getOperand(1));
   if (!RHS || !RHS->getValue().isMask())
     return false;
@@ -1124,7 +1124,7 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
   // We can only replace the AND with LHS based on range info if the range does
   // not include undef.
   ConstantRange LRange =
-      LVI->getConstantRange(LHS, BinOp, /*UndefAllowed=*/false);
+      LVI->getConstantRangeAtUse(LHS, /*UndefAllowed=*/false);
   if (!LRange.getUnsignedMax().ule(RHS->getValue()))
     return false;
 
index 58d71b4..2b25195 100644 (file)
@@ -362,9 +362,11 @@ define i16 @urem_expand(i16 %x) {
 
 define i16 @urem_narrow(i16 %x) {
 ; CHECK-LABEL: @urem_narrow(
-; CHECK-NEXT:    [[UREM:%.*]] = urem i16 [[X:%.*]], 42
+; CHECK-NEXT:    [[UREM_LHS_TRUNC:%.*]] = trunc i16 [[X:%.*]] to i8
+; CHECK-NEXT:    [[UREM1:%.*]] = urem i8 [[UREM_LHS_TRUNC]], 42
+; CHECK-NEXT:    [[UREM_ZEXT:%.*]] = zext i8 [[UREM1]] to i16
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[X]], 85
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i16 [[UREM]], i16 24
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i16 [[UREM_ZEXT]], i16 24
 ; CHECK-NEXT:    ret i16 [[SEL]]
 ;
   %urem = urem i16 %x, 42
@@ -388,11 +390,10 @@ define i16 @urem_insufficient(i16 %x) {
 
 define i16 @srem_elide(i16 %x) {
 ; CHECK-LABEL: @srem_elide(
-; CHECK-NEXT:    [[SREM:%.*]] = srem i16 [[X:%.*]], 42
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i16 [[X]], 42
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i16 [[X:%.*]], 42
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i16 [[X]], -42
 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i16 [[SREM]], i16 24
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i16 [[X]], i16 24
 ; CHECK-NEXT:    ret i16 [[SEL]]
 ;
   %srem = srem i16 %x, 42
@@ -403,6 +404,25 @@ define i16 @srem_elide(i16 %x) {
   ret i16 %sel
 }
 
+define i16 @srem_narrow(i16 %x) {
+; CHECK-LABEL: @srem_narrow(
+; CHECK-NEXT:    [[SREM_LHS_TRUNC:%.*]] = trunc i16 [[X:%.*]] to i8
+; CHECK-NEXT:    [[SREM1:%.*]] = srem i8 [[SREM_LHS_TRUNC]], 42
+; CHECK-NEXT:    [[SREM_SEXT:%.*]] = sext i8 [[SREM1]] to i16
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i16 [[X]], 43
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i16 [[X]], -43
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i16 [[SREM_SEXT]], i16 24
+; CHECK-NEXT:    ret i16 [[SEL]]
+;
+  %srem = srem i16 %x, 42
+  %cmp1 = icmp slt i16 %x, 43
+  %cmp2 = icmp sgt i16 %x, -43
+  %and = and i1 %cmp1, %cmp2
+  %sel = select i1 %and, i16 %srem, i16 24
+  ret i16 %sel
+}
+
 define i16 @srem_convert(i16 %x) {
 ; CHECK-LABEL: @srem_convert(
 ; CHECK-NEXT:    [[SREM:%.*]] = srem i16 [[X:%.*]], 42
@@ -522,9 +542,8 @@ define i16 @infer_flags(i16 %x) {
 
 define i16 @and_elide(i16 %x) {
 ; CHECK-LABEL: @and_elide(
-; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 7
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[X]], 8
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i16 [[AND]], i16 24
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 8
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
 ; CHECK-NEXT:    ret i16 [[SEL]]
 ;
   %and = and i16 %x, 7