Skip to content

Commit 810b5c4

Browse files
committed
[NewGVN] add context instruction for SimplifyQuery
NewGVN will find operator from other context. ValueTracking currently doesn't have a way to run completely without context instruction. So it will use operator itself as conext instruction. If the operator in another branch will never be executed but it has an assume, it may caused value tracking use the assume to do wrong simpilfy. It would be better to make these simplification queries not use context at all, but that would require some API changes. For now we just use the orignial instruction as context instruction to fix the issue. Fix llvm#56039 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D127942
1 parent 8f891b7 commit 810b5c4

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

llvm/lib/Transforms/Scalar/NewGVN.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,9 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
10741074
Value *Arg1, Value *Arg2,
10751075
Instruction *I) const {
10761076
auto *E = new (ExpressionAllocator) BasicExpression(2);
1077+
// TODO: we need to remove context instruction after Value Tracking
1078+
// can run without context instruction
1079+
const SimplifyQuery Q = SQ.getWithInstruction(I);
10771080

10781081
E->setType(T);
10791082
E->setOpcode(Opcode);
@@ -1089,7 +1092,7 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
10891092
E->op_push_back(lookupOperandLeader(Arg1));
10901093
E->op_push_back(lookupOperandLeader(Arg2));
10911094

1092-
Value *V = simplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ);
1095+
Value *V = simplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), Q);
10931096
if (auto Simplified = checkExprResults(E, I, V)) {
10941097
addAdditionalUsers(Simplified, I);
10951098
return Simplified.Expr;
@@ -1145,6 +1148,9 @@ NewGVN::ExprResult NewGVN::checkExprResults(Expression *E, Instruction *I,
11451148

11461149
NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
11471150
auto *E = new (ExpressionAllocator) BasicExpression(I->getNumOperands());
1151+
// TODO: we need to remove context instruction after Value Tracking
1152+
// can run without context instruction
1153+
const SimplifyQuery Q = SQ.getWithInstruction(I);
11481154

11491155
bool AllConstant = setBasicExpressionInfo(I, E);
11501156

@@ -1173,7 +1179,7 @@ NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
11731179
assert((E->getOperand(0)->getType() == I->getOperand(0)->getType() &&
11741180
E->getOperand(1)->getType() == I->getOperand(1)->getType()));
11751181
Value *V =
1176-
simplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), SQ);
1182+
simplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), Q);
11771183
if (auto Simplified = checkExprResults(E, I, V))
11781184
return Simplified;
11791185
} else if (isa<SelectInst>(I)) {
@@ -1182,25 +1188,25 @@ NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
11821188
assert(E->getOperand(1)->getType() == I->getOperand(1)->getType() &&
11831189
E->getOperand(2)->getType() == I->getOperand(2)->getType());
11841190
Value *V = simplifySelectInst(E->getOperand(0), E->getOperand(1),
1185-
E->getOperand(2), SQ);
1191+
E->getOperand(2), Q);
11861192
if (auto Simplified = checkExprResults(E, I, V))
11871193
return Simplified;
11881194
}
11891195
} else if (I->isBinaryOp()) {
11901196
Value *V =
1191-
simplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), SQ);
1197+
simplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), Q);
11921198
if (auto Simplified = checkExprResults(E, I, V))
11931199
return Simplified;
11941200
} else if (auto *CI = dyn_cast<CastInst>(I)) {
11951201
Value *V =
1196-
simplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), SQ);
1202+
simplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), Q);
11971203
if (auto Simplified = checkExprResults(E, I, V))
11981204
return Simplified;
11991205
} else if (auto *GEPI = dyn_cast<GetElementPtrInst>(I)) {
12001206
Value *V =
12011207
simplifyGEPInst(GEPI->getSourceElementType(), *E->op_begin(),
12021208
makeArrayRef(std::next(E->op_begin()), E->op_end()),
1203-
GEPI->isInBounds(), SQ);
1209+
GEPI->isInBounds(), Q);
12041210
if (auto Simplified = checkExprResults(E, I, V))
12051211
return Simplified;
12061212
} else if (AllConstant) {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=newgvn -S | FileCheck %s
3+
4+
; github issue #56039
5+
define i8 @src(i8* %a, i8* %b, i1 %c) {
6+
; CHECK-LABEL: @src(
7+
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
8+
; CHECK: bb1:
9+
; CHECK-NEXT: [[LB1:%.*]] = load i8, i8* [[B:%.*]], align 1
10+
; CHECK-NEXT: [[TOBOOL3_NOT_I:%.*]] = icmp eq i8 [[LB1]], 0
11+
; CHECK-NEXT: br i1 [[TOBOOL3_NOT_I]], label [[BB4:%.*]], label [[BB3:%.*]]
12+
; CHECK: bb2:
13+
; CHECK-NEXT: [[LB2:%.*]] = load i8, i8* [[B]], align 1
14+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 0, [[LB2]]
15+
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP_NOT_I]])
16+
; CHECK-NEXT: br label [[BB3]]
17+
; CHECK: bb3:
18+
; CHECK-NEXT: [[LA:%.*]] = load i8, i8* [[A:%.*]], align 1
19+
; CHECK-NEXT: br label [[BB4]]
20+
; CHECK: bb4:
21+
; CHECK-NEXT: ret i8 0
22+
;
23+
br i1 %c, label %bb1, label %bb2
24+
25+
bb1:
26+
%lb1 = load i8, i8* %b
27+
%tobool3.not.i = icmp eq i8 %lb1, 0
28+
br i1 %tobool3.not.i, label %bb4, label %bb3
29+
30+
bb2:
31+
%lb2 = load i8, i8* %b
32+
%cmp.not.i = icmp ult i8 0, %lb2
33+
tail call void @llvm.assume(i1 %cmp.not.i)
34+
br label %bb3
35+
36+
bb3:
37+
%p = phi i8 [ %lb1, %bb1 ], [ %lb2, %bb2 ]
38+
%la = load i8, i8* %a
39+
%xor = xor i8 %la, %p
40+
br label %bb4
41+
42+
bb4:
43+
ret i8 0
44+
}
45+
46+
declare void @llvm.assume(i1)

0 commit comments

Comments
 (0)