[llvm] r374506 - [CVP] Remove a masking operation if range information implies it's a noop
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 20:48:56 PDT 2019
Author: reames
Date: Thu Oct 10 20:48:56 2019
New Revision: 374506
URL: http://llvm.org/viewvc/llvm-project?rev=374506&view=rev
Log:
[CVP] Remove a masking operation if range information implies it's a noop
This is really a known bits style transformation, but known bits isn't context sensitive. The particular case which comes up happens to involve a range which allows range based reasoning to eliminate the mask pattern, so handle that case specifically in CVP.
InstCombine likes to generate the mask-by-low-bits pattern when widening an arithmetic expression which includes a zext in the middle.
Differential Revision: https://reviews.llvm.org/D68811
Added:
llvm/trunk/test/Transforms/CorrelatedValuePropagation/and.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll
llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
Modified: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp?rev=374506&r1=374505&r2=374506&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp Thu Oct 10 20:48:56 2019
@@ -63,6 +63,7 @@ STATISTIC(NumUDivs, "Number of udivs
STATISTIC(NumAShrs, "Number of ashr converted to lshr");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumSExt, "Number of sext converted to zext");
+STATISTIC(NumAnd, "Number of ands removed");
STATISTIC(NumOverflows, "Number of overflow checks removed");
STATISTIC(NumSaturating,
"Number of saturating arithmetics converted to normal arithmetics");
@@ -700,6 +701,29 @@ static bool processBinOp(BinaryOperator
return Changed;
}
+static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
+ if (BinOp->getType()->isVectorTy())
+ return false;
+
+ // 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.
+ BasicBlock *BB = BinOp->getParent();
+ Value *LHS = BinOp->getOperand(0);
+ ConstantInt *RHS = dyn_cast<ConstantInt>(BinOp->getOperand(1));
+ if (!RHS || !RHS->getValue().isMask())
+ return false;
+
+ ConstantRange LRange = LVI->getConstantRange(LHS, BB, BinOp);
+ if (!LRange.getUnsignedMax().ule(RHS->getValue()))
+ return false;
+
+ BinOp->replaceAllUsesWith(LHS);
+ BinOp->eraseFromParent();
+ NumAnd++;
+ return true;
+}
+
+
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
if (Constant *C = LVI->getConstant(V, At->getParent(), At))
return C;
@@ -774,6 +798,9 @@ static bool runImpl(Function &F, LazyVal
case Instruction::Sub:
BBChanged |= processBinOp(cast<BinaryOperator>(II), LVI);
break;
+ case Instruction::And:
+ BBChanged |= processAnd(cast<BinaryOperator>(II), LVI);
+ break;
}
}
Added: llvm/trunk/test/Transforms/CorrelatedValuePropagation/and.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/and.ll?rev=374506&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/and.ll (added)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/and.ll Thu Oct 10 20:48:56 2019
@@ -0,0 +1,127 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -correlated-propagation -S | FileCheck %s
+
+define i32 @test(i32 %a) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 128
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: ret i32 [[A]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ult i32 %a, 128
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 255
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
+define i32 @test2(i32 %a) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 256
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: ret i32 [[A]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ult i32 %a, 256
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 255
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
+define i32 @test3(i32 %a) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 256
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: ret i32 [[A]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ult i32 %a, 256
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 1023
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
+
+define i32 @neg1(i32 %a) {
+; CHECK-LABEL: @neg1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A:%.*]], 256
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 255
+; CHECK-NEXT: ret i32 [[AND]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ule i32 %a, 256
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 255
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
+define i32 @neg2(i32 %a) {
+; CHECK-LABEL: @neg2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 513
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 255
+; CHECK-NEXT: ret i32 [[AND]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ult i32 %a, 513
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 255
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
+define i32 @neg3(i32 %a) {
+; CHECK-LABEL: @neg3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 256
+; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]]
+; CHECK: continue:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 254
+; CHECK-NEXT: ret i32 [[AND]]
+; CHECK: exit:
+; CHECK-NEXT: ret i32 -1
+;
+entry:
+ %cmp = icmp ult i32 %a, 256
+ br i1 %cmp, label %continue, label %exit
+continue:
+ %and = and i32 %a, 254
+ ret i32 %and
+exit:
+ ret i32 -1
+}
+
Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll?rev=374506&r1=374505&r2=374506&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll Thu Oct 10 20:48:56 2019
@@ -1023,7 +1023,6 @@ define i1 @smul_and_cmp(i32 %x, i32 %y)
; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
; CHECK-NEXT: br label [[CONT3:%.*]]
; CHECK: cont3:
-; CHECK-NEXT: [[CMP5:%.*]] = and i1 true, true
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret i1 true
Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll?rev=374506&r1=374505&r2=374506&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/range.ll Thu Oct 10 20:48:56 2019
@@ -745,10 +745,9 @@ target93:
define i1 @test17_i1(i1 %a) {
; CHECK-LABEL: @test17_i1(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], true
; CHECK-NEXT: br label [[DISPATCH:%.*]]
; CHECK: dispatch:
-; CHECK-NEXT: br i1 [[A]], label [[TRUE:%.*]], label [[DISPATCH]]
+; CHECK-NEXT: br i1 [[A:%.*]], label [[TRUE:%.*]], label [[DISPATCH]]
; CHECK: true:
; CHECK-NEXT: ret i1 true
;
More information about the llvm-commits
mailing list