Skip to content

Commit c9832da

Browse files
authored
[CGP] Drop nneg flag when moving zext past instruction (#72103)
Fix the issue by not reusing the zext at all. The code already handles creation of new zexts if more than one is needed. Always use that code-path instead of trying to reuse the old zext in some case. (Alternatively we could also drop poison-generating flags on the old zext, but it seems cleaner to not reuse it at all, especially if it's not always possible anyway.) Fixes #72046.
1 parent e96edde commit c9832da

File tree

5 files changed

+35
-30
lines changed

5 files changed

+35
-30
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4568,8 +4568,6 @@ Value *TypePromotionHelper::promoteOperandForOther(
45684568
// Step #2.
45694569
TPT.replaceAllUsesWith(Ext, ExtOpnd);
45704570
// Step #3.
4571-
Instruction *ExtForOpnd = Ext;
4572-
45734571
LLVM_DEBUG(dbgs() << "Propagate Ext to operands\n");
45744572
for (int OpIdx = 0, EndOpIdx = ExtOpnd->getNumOperands(); OpIdx != EndOpIdx;
45754573
++OpIdx) {
@@ -4597,33 +4595,21 @@ Value *TypePromotionHelper::promoteOperandForOther(
45974595
}
45984596

45994597
// Otherwise we have to explicitly sign extend the operand.
4600-
// Check if Ext was reused to extend an operand.
4601-
if (!ExtForOpnd) {
4602-
// If yes, create a new one.
4603-
LLVM_DEBUG(dbgs() << "More operands to ext\n");
4604-
Value *ValForExtOpnd = IsSExt ? TPT.createSExt(Ext, Opnd, Ext->getType())
4605-
: TPT.createZExt(Ext, Opnd, Ext->getType());
4606-
if (!isa<Instruction>(ValForExtOpnd)) {
4607-
TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
4608-
continue;
4609-
}
4610-
ExtForOpnd = cast<Instruction>(ValForExtOpnd);
4611-
}
4598+
Value *ValForExtOpnd = IsSExt
4599+
? TPT.createSExt(ExtOpnd, Opnd, Ext->getType())
4600+
: TPT.createZExt(ExtOpnd, Opnd, Ext->getType());
4601+
TPT.setOperand(ExtOpnd, OpIdx, ValForExtOpnd);
4602+
Instruction *InstForExtOpnd = dyn_cast<Instruction>(ValForExtOpnd);
4603+
if (!InstForExtOpnd)
4604+
continue;
4605+
46124606
if (Exts)
4613-
Exts->push_back(ExtForOpnd);
4614-
TPT.setOperand(ExtForOpnd, 0, Opnd);
4607+
Exts->push_back(InstForExtOpnd);
46154608

4616-
// Move the sign extension before the insertion point.
4617-
TPT.moveBefore(ExtForOpnd, ExtOpnd);
4618-
TPT.setOperand(ExtOpnd, OpIdx, ExtForOpnd);
4619-
CreatedInstsCost += !TLI.isExtFree(ExtForOpnd);
4620-
// If more sext are required, new instructions will have to be created.
4621-
ExtForOpnd = nullptr;
4622-
}
4623-
if (ExtForOpnd == Ext) {
4624-
LLVM_DEBUG(dbgs() << "Extension is useless now\n");
4625-
TPT.eraseInstruction(Ext);
4609+
CreatedInstsCost += !TLI.isExtFree(InstForExtOpnd);
46264610
}
4611+
LLVM_DEBUG(dbgs() << "Extension is useless now\n");
4612+
TPT.eraseInstruction(Ext);
46274613
return ExtOpnd;
46284614
}
46294615

llvm/test/Transforms/CodeGenPrepare/X86/multi-extension.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ declare void @bar(i64)
1010
; %or is reachable by both a sext and zext that are going to be promoted.
1111
; It ensures correct operation on PromotedInsts.
1212

13-
; CHECK: %promoted = trunc i32 %or to i16
14-
; CHECK-NEXT: %c = sext i16 %promoted to i64
13+
; CHECK: %promoted3 = trunc i32 %or to i16
14+
; CHECK-NEXT: %c = sext i16 %promoted3 to i64
1515
define i32 @foo(i16 %kkk) {
1616
entry:
1717
%t4 = load i16, ptr @b, align 2
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt -S -codegenprepare -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
3+
4+
; Make sure the nneg flag is dropped when lshr and zext are interchanged.
5+
define i8 @get(ptr %box, i32 %in) {
6+
; CHECK-LABEL: define i8 @get(
7+
; CHECK-SAME: ptr [[BOX:%.*]], i32 [[IN:%.*]]) {
8+
; CHECK-NEXT: [[PROMOTED:%.*]] = zext i32 [[IN]] to i64
9+
; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[PROMOTED]], 24
10+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[BOX]], i64 [[SHR]]
11+
; CHECK-NEXT: [[RES:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
12+
; CHECK-NEXT: ret i8 [[RES]]
13+
;
14+
%shr = lshr i32 %in, 24
15+
%idxprom = zext nneg i32 %shr to i64
16+
%arrayidx = getelementptr inbounds i8, ptr %box, i64 %idxprom
17+
%res = load i8, ptr %arrayidx, align 1
18+
ret i8 %res
19+
}

llvm/test/Transforms/CodeGenPrepare/X86/promoted-trunc-loc.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck %s --match-full-lines
22

33
; Make sure the promoted trunc doesn't get a debug location associated.
4-
; CHECK: %promoted = trunc i32 %or to i16
4+
; CHECK: %promoted3 = trunc i32 %or to i16
55

66
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
77
target triple = "x86_64-apple-macosx10.13.0"

llvm/test/Transforms/CodeGenPrepare/X86/promoted-zext-debugloc.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck %s --match-full-lines
22

33
; Make sure the promoted zext doesn't get a debug location associated.
4-
; CHECK: %promoted = zext i8 %t to i64
4+
; CHECK: %promoted1 = zext i8 %t to i64
55

66
define void @patatino(ptr %p, ptr %q, i32 %b, ptr %addr) !dbg !6 {
77
entry:

0 commit comments

Comments
 (0)