Skip to content

Commit b2fd3c7

Browse files
committed
[SCCP] Remove masking operations
1 parent 7e1fa09 commit b2fd3c7

File tree

4 files changed

+23
-13
lines changed

4 files changed

+23
-13
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/Analysis/ValueLatticeUtils.h"
2121
#include "llvm/Analysis/ValueTracking.h"
2222
#include "llvm/IR/InstVisitor.h"
23+
#include "llvm/IR/PatternMatch.h"
2324
#include "llvm/Support/Casting.h"
2425
#include "llvm/Support/Debug.h"
2526
#include "llvm/Support/ErrorHandling.h"
@@ -30,6 +31,7 @@
3031
#include <vector>
3132

3233
using namespace llvm;
34+
using namespace PatternMatch;
3335

3436
#define DEBUG_TYPE "sccp"
3537

@@ -86,7 +88,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
8688
/// Try to use \p Inst's value range from \p Solver to infer the NUW flag.
8789
static bool refineInstruction(SCCPSolver &Solver,
8890
const SmallPtrSetImpl<Value *> &InsertedValues,
89-
Instruction &Inst) {
91+
Instruction &Inst, Statistic &InstRemovedStat) {
9092
bool Changed = false;
9193
auto GetRange = [&Solver, &InsertedValues](Value *Op) {
9294
if (auto *Const = dyn_cast<Constant>(Op))
@@ -99,6 +101,9 @@ static bool refineInstruction(SCCPSolver &Solver,
99101
Op->getType(), /*UndefAllowed=*/false);
100102
};
101103

104+
Value *X;
105+
const APInt *RHSC;
106+
102107
if (isa<OverflowingBinaryOperator>(Inst)) {
103108
if (Inst.hasNoSignedWrap() && Inst.hasNoUnsignedWrap())
104109
return false;
@@ -157,6 +162,15 @@ static bool refineInstruction(SCCPSolver &Solver,
157162
GEPNoWrapFlags::noUnsignedWrap());
158163
Changed = true;
159164
}
165+
} else if (match(&Inst, m_And(m_Value(X), m_LowBitMask(RHSC)))) {
166+
ConstantRange LRange = GetRange(Inst.getOperand(0));
167+
if (!LRange.getUnsignedMax().ule(*RHSC))
168+
return false;
169+
170+
Inst.replaceAllUsesWith(X);
171+
Inst.eraseFromParent();
172+
++InstRemovedStat;
173+
Changed = true;
160174
}
161175

162176
return Changed;
@@ -249,7 +263,8 @@ bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
249263
} else if (replaceSignedInst(*this, InsertedValues, Inst)) {
250264
MadeChanges = true;
251265
++InstReplacedStat;
252-
} else if (refineInstruction(*this, InsertedValues, Inst)) {
266+
} else if (refineInstruction(*this, InsertedValues, Inst,
267+
InstRemovedStat)) {
253268
MadeChanges = true;
254269
}
255270
}

llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ define void @val_undef_range() {
4646
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
4747
; CHECK: true:
4848
; CHECK-NEXT: call void @use(i1 false)
49-
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
50-
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
49+
; CHECK-NEXT: call void @use.i32(i32 [[A]])
5150
; CHECK-NEXT: ret void
5251
; CHECK: false:
5352
; CHECK-NEXT: ret void
@@ -82,8 +81,7 @@ define void @val_singlecrfromundef_range(i1 %cond) {
8281
; CHECK-NEXT: br label [[TRUE:%.*]]
8382
; CHECK: true:
8483
; CHECK-NEXT: call void @use(i1 false)
85-
; CHECK-NEXT: [[P_127:%.*]] = and i32 10, 127
86-
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
84+
; CHECK-NEXT: call void @use.i32(i32 10)
8785
; CHECK-NEXT: ret void
8886
;
8987
entry:
@@ -131,8 +129,7 @@ define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) {
131129
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
132130
; CHECK: true:
133131
; CHECK-NEXT: call void @use(i1 false)
134-
; CHECK-NEXT: [[P_127:%.*]] = and i32 [[P]], 127
135-
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
132+
; CHECK-NEXT: call void @use.i32(i32 [[P]])
136133
; CHECK-NEXT: ret void
137134
; CHECK: false:
138135
; CHECK-NEXT: ret void

llvm/test/Transforms/SCCP/range-and.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt -S -passes=sccp %s | FileCheck %s
33

44
declare void @use(i1)
@@ -140,9 +140,8 @@ define i64 @constant_range_and_255_100(i1 %cond, i64 %a) {
140140
; CHECK-NEXT: br label [[BB3]]
141141
; CHECK: bb3:
142142
; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R_1]], [[BB1]] ], [ [[R_2]], [[BB2]] ]
143-
; CHECK-NEXT: [[P_AND:%.*]] = and i64 [[P]], 255
144143
; CHECK-NEXT: call void @use(i1 true)
145-
; CHECK-NEXT: ret i64 [[P_AND]]
144+
; CHECK-NEXT: ret i64 [[P]]
146145
;
147146
entry:
148147
br i1 %cond, label %bb1, label %bb2

llvm/test/Transforms/SCCP/range-with-undef.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ define i8 @test_binop(i1 %cond, i8 %a) {
1212
; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 [[A]] to i16
1313
; CHECK-NEXT: br label %[[JOIN]]
1414
; CHECK: [[JOIN]]:
15-
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
16-
; CHECK-NEXT: [[AND:%.*]] = and i16 [[PHI]], -1
15+
; CHECK-NEXT: [[AND:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
1716
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[AND]] to i8
1817
; CHECK-NEXT: ret i8 [[TRUNC]]
1918
;

0 commit comments

Comments
 (0)