Skip to content

Commit a84d0f7

Browse files
skarczewigcbot
authored andcommitted
Handle negative numbers ext after constant sinking
Handle negative numbers ext after constant sinking
1 parent 8759c64 commit a84d0f7

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

IGC/Compiler/CISACodeGen/PushAnalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ bool PushAnalysis::IsStatelessCBLoad(llvm::Instruction *inst, int &pushableAddre
172172
if (pAdd && pAdd->getOpcode() == llvm::Instruction::Add) {
173173
GetPotentialPushableAddresses(pAdd->getOperand(0));
174174
GetPotentialPushableAddresses(pAdd->getOperand(1));
175-
} else if (isa<ZExtInst>(pAddress)) {
176-
GetPotentialPushableAddresses(cast<ZExtInst>(pAddress)->getOperand(0));
175+
} else if (isa<ZExtInst>(pAddress) || isa<SExtInst>(pAddress)) {
176+
GetPotentialPushableAddresses(cast<Instruction>(pAddress)->getOperand(0));
177177
} else if (isa<ConstantInt>(pAddress)) {
178178
ConstantInt *pConst = cast<ConstantInt>(pAddress);
179179
offset += pConst->getZExtValue();

IGC/Compiler/Optimizer/SinkPointerConstAdd.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class SinkPointerConstAddPass : public llvm::FunctionPass {
4141
static char ID;
4242

4343
private:
44-
bool getConstantOffset(llvm::Value *value, int &offset);
44+
bool getConstantOffset(llvm::Value *value, std::vector<llvm::Instruction *> &zexts, int &offset);
45+
void zextToSext(std::vector<llvm::Instruction *> &zexts);
4546
};
4647

4748
#define PASS_FLAG "igc-sink-ptr-const-add"
@@ -50,7 +51,8 @@ class SinkPointerConstAddPass : public llvm::FunctionPass {
5051
#define PASS_ANALYSIS false
5152
IGC_INITIALIZE_PASS(SinkPointerConstAddPass, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
5253

53-
bool SinkPointerConstAddPass::getConstantOffset(llvm::Value *value, int &offset) {
54+
bool SinkPointerConstAddPass::getConstantOffset(llvm::Value *value, std::vector<llvm::Instruction *> &zexts,
55+
int &offset) {
5456
// Recursively search for constant add operations - this will stop after the first const add found,
5557
// and should be called repeatedly until no more const adds can be sunk.
5658

@@ -61,11 +63,15 @@ bool SinkPointerConstAddPass::getConstantOffset(llvm::Value *value, int &offset)
6163
if (llvm::Instruction *instr = llvm::dyn_cast<llvm::Instruction>(value)) {
6264
if (instr->getOpcode() == llvm::Instruction::Trunc || instr->getOpcode() == llvm::Instruction::ZExt ||
6365
instr->getOpcode() == llvm::Instruction::SExt) {
66+
// Collect zext instructions for later processing
67+
if (instr->getOpcode() == llvm::Instruction::ZExt) {
68+
zexts.push_back(instr);
69+
}
6470
// Skip cast instructions
6571
llvm::Instruction *op = llvm::dyn_cast<llvm::Instruction>(instr->getOperand(0));
6672
// This is a simple pass, only sink within the same basic block
6773
if (op && instr->getParent() == op->getParent()) {
68-
return getConstantOffset(instr->getOperand(0), offset);
74+
return getConstantOffset(instr->getOperand(0), zexts, offset);
6975
} else {
7076
return false;
7177
}
@@ -89,8 +95,8 @@ bool SinkPointerConstAddPass::getConstantOffset(llvm::Value *value, int &offset)
8995
llvm::Instruction *op0 = llvm::dyn_cast<llvm::Instruction>(instr->getOperand(0));
9096
llvm::Instruction *op1 = llvm::dyn_cast<llvm::Instruction>(instr->getOperand(1));
9197
// This is a simple pass, only sink within the same basic block
92-
return (op0 && instr->getParent() == op0->getParent() && getConstantOffset(op0, offset)) ? true
93-
: (op1 && instr->getParent() == op1->getParent()) ? getConstantOffset(op1, offset)
98+
return (op0 && instr->getParent() == op0->getParent() && getConstantOffset(op0, zexts, offset)) ? true
99+
: (op1 && instr->getParent() == op1->getParent()) ? getConstantOffset(op1, zexts, offset)
94100
: false;
95101
}
96102
}
@@ -99,6 +105,19 @@ bool SinkPointerConstAddPass::getConstantOffset(llvm::Value *value, int &offset)
99105
return false;
100106
}
101107

108+
void SinkPointerConstAddPass::zextToSext(std::vector<llvm::Instruction *> &zexts) {
109+
// Remove duplicates
110+
std::sort(zexts.begin(), zexts.end());
111+
zexts.erase(std::unique(zexts.begin(), zexts.end()), zexts.end());
112+
// Convert zext instructions to sext instructions
113+
for (auto &zext : zexts) {
114+
llvm::IRBuilder<> builder(zext);
115+
llvm::Value *sext = builder.CreateSExt(zext->getOperand(0), zext->getType());
116+
zext->replaceAllUsesWith(sext);
117+
zext->eraseFromParent();
118+
}
119+
}
120+
102121
bool SinkPointerConstAddPass::runOnFunction(llvm::Function &F) {
103122
bool changed = false;
104123
std::vector<llvm::IntToPtrInst *> intToPtrInsts;
@@ -115,11 +134,20 @@ bool SinkPointerConstAddPass::runOnFunction(llvm::Function &F) {
115134

116135
for (auto &intrinsic : intToPtrInsts) {
117136
int offset = 0;
137+
bool localChanged = false;
138+
std::vector<llvm::Instruction *> zexts;
118139
// Keep sinking constant adds until no more can be sunk
119-
while (getConstantOffset(intrinsic->getOperand(0), offset)) {
140+
while (getConstantOffset(intrinsic->getOperand(0), zexts, offset)) {
141+
localChanged = true;
120142
changed = true;
121143
}
122144

145+
if (localChanged) {
146+
// In some cases, sinking constant add may introduce negative values in pointer calculations.
147+
// Convert affected zext instructions to sext instructions to avoid potential issues.
148+
zextToSext(zexts);
149+
}
150+
123151
// If we found any constant offset, create new pointer calculation
124152
if (offset != 0) {
125153
llvm::IRBuilder<> builder(intrinsic);

IGC/Compiler/tests/SinkPointerConstAdd/basic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ GlobalScopeInitialization:
2121
%1 = call i64 @llvm.genx.GenISA.RuntimeValue.i64(i32 2)
2222
%2 = add i32 %0, 128
2323
%3 = zext i32 %2 to i64
24-
; CHECK: %2 = zext i32 %0 to i64
24+
; CHECK: %2 = sext i32 %0 to i64
2525
%4 = add i64 %1, %3
2626
; CHECK-NEXT: %3 = add i64 %1, %2
2727
; CHECK-NEXT: %4 = add i64 %3, 128

IGC/Compiler/tests/SinkPointerConstAdd/recursiveSub.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ GlobalScopeInitialization:
2222
%2 = add i32 %0, 128
2323
%3 = sub i32 %2, 128
2424
%4 = zext i32 %3 to i64
25-
; CHECK: %2 = zext i32 %0 to i64
25+
; CHECK: %2 = sext i32 %0 to i64
2626
%5 = add i64 %1, %4
2727
; CHECK-NEXT: %3 = add i64 %1, %2
2828
%ptr = inttoptr i64 %5 to i32 addrspace(1)*

0 commit comments

Comments
 (0)