Skip to content

Commit ed96430

Browse files
authored
[SCCP] Infer nneg on existing zext (#72143)
This patch infers `nneg` flags for existing zext instructions in SCCP. Similar patch: #72052
1 parent f633f32 commit ed96430

File tree

3 files changed

+28
-21
lines changed

3 files changed

+28
-21
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
107107
static bool refineInstruction(SCCPSolver &Solver,
108108
const SmallPtrSetImpl<Value *> &InsertedValues,
109109
Instruction &Inst) {
110-
if (!isa<OverflowingBinaryOperator>(Inst))
111-
return false;
112-
110+
bool Changed = false;
113111
auto GetRange = [&Solver, &InsertedValues](Value *Op) {
114112
if (auto *Const = dyn_cast<ConstantInt>(Op))
115113
return ConstantRange(Const->getValue());
@@ -120,23 +118,32 @@ static bool refineInstruction(SCCPSolver &Solver,
120118
return getConstantRange(Solver.getLatticeValueFor(Op), Op->getType(),
121119
/*UndefAllowed=*/false);
122120
};
123-
auto RangeA = GetRange(Inst.getOperand(0));
124-
auto RangeB = GetRange(Inst.getOperand(1));
125-
bool Changed = false;
126-
if (!Inst.hasNoUnsignedWrap()) {
127-
auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
128-
Instruction::BinaryOps(Inst.getOpcode()), RangeB,
129-
OverflowingBinaryOperator::NoUnsignedWrap);
130-
if (NUWRange.contains(RangeA)) {
131-
Inst.setHasNoUnsignedWrap();
132-
Changed = true;
121+
122+
if (isa<OverflowingBinaryOperator>(Inst)) {
123+
auto RangeA = GetRange(Inst.getOperand(0));
124+
auto RangeB = GetRange(Inst.getOperand(1));
125+
if (!Inst.hasNoUnsignedWrap()) {
126+
auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
127+
Instruction::BinaryOps(Inst.getOpcode()), RangeB,
128+
OverflowingBinaryOperator::NoUnsignedWrap);
129+
if (NUWRange.contains(RangeA)) {
130+
Inst.setHasNoUnsignedWrap();
131+
Changed = true;
132+
}
133133
}
134-
}
135-
if (!Inst.hasNoSignedWrap()) {
136-
auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
137-
Instruction::BinaryOps(Inst.getOpcode()), RangeB, OverflowingBinaryOperator::NoSignedWrap);
138-
if (NSWRange.contains(RangeA)) {
139-
Inst.setHasNoSignedWrap();
134+
if (!Inst.hasNoSignedWrap()) {
135+
auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
136+
Instruction::BinaryOps(Inst.getOpcode()), RangeB,
137+
OverflowingBinaryOperator::NoSignedWrap);
138+
if (NSWRange.contains(RangeA)) {
139+
Inst.setHasNoSignedWrap();
140+
Changed = true;
141+
}
142+
}
143+
} else if (isa<ZExtInst>(Inst) && !Inst.hasNonNeg()) {
144+
auto Range = GetRange(Inst.getOperand(0));
145+
if (Range.isAllNonNegative()) {
146+
Inst.setNonNeg();
140147
Changed = true;
141148
}
142149
}

llvm/test/Transforms/SCCP/ip-ranges-casts.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ define i1 @caller1() {
5959
; x = [100, 301)
6060
define internal i1 @f.zext(i32 %x, i32 %y) {
6161
; CHECK-LABEL: @f.zext(
62-
; CHECK-NEXT: [[T_1:%.*]] = zext i32 [[X:%.*]] to i64
62+
; CHECK-NEXT: [[T_1:%.*]] = zext nneg i32 [[X:%.*]] to i64
6363
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i64 [[T_1]], 299
6464
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i64 [[T_1]], 101
6565
; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]

llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ define i64 @crash_ctpop(i1 %cond, ptr %addr) {
174174
; CHECK: if.else:
175175
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[ADDR:%.*]], align 8
176176
; CHECK-NEXT: [[ANDV:%.*]] = and i32 [[LV]], 16777215
177-
; CHECK-NEXT: [[TRUNCV:%.*]] = zext i32 [[ANDV]] to i64
177+
; CHECK-NEXT: [[TRUNCV:%.*]] = zext nneg i32 [[ANDV]] to i64
178178
; CHECK-NEXT: [[RES:%.*]] = tail call i64 @llvm.ctpop.i64(i64 [[TRUNCV]])
179179
; CHECK-NEXT: ret i64 [[RES]]
180180
;

0 commit comments

Comments
 (0)