Skip to content

Commit be7f851

Browse files
[CGP] Fix missing sign extension for base offset in optimizeMemoryInst (#161377)
If we have integers larger than 64-bit we need to explicitly sign extend them, otherwise we will get wrong zero extended values.
1 parent 50cda17 commit be7f851

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,7 +3194,7 @@ struct ExtAddrMode : public TargetLowering::AddrMode {
31943194
case ScaledRegField:
31953195
return ScaledReg;
31963196
case BaseOffsField:
3197-
return ConstantInt::get(IntPtrTy, BaseOffs);
3197+
return ConstantInt::getSigned(IntPtrTy, BaseOffs);
31983198
}
31993199
}
32003200

@@ -6100,7 +6100,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
61006100

61016101
// Add in the Base Offset if present.
61026102
if (AddrMode.BaseOffs) {
6103-
Value *V = ConstantInt::get(IntPtrTy, AddrMode.BaseOffs);
6103+
Value *V = ConstantInt::getSigned(IntPtrTy, AddrMode.BaseOffs);
61046104
if (ResultIndex) {
61056105
// We need to add this separately from the scale above to help with
61066106
// SDAG consecutive load/store merging.
@@ -6226,7 +6226,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
62266226

62276227
// Add in the Base Offset if present.
62286228
if (AddrMode.BaseOffs) {
6229-
Value *V = ConstantInt::get(IntPtrTy, AddrMode.BaseOffs);
6229+
Value *V = ConstantInt::getSigned(IntPtrTy, AddrMode.BaseOffs);
62306230
if (Result)
62316231
Result = Builder.CreateAdd(Result, V, "sunkaddr");
62326232
else
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' < %s | FileCheck --check-prefix=GEP %s
3+
; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -addr-sink-using-gep=false < %s | FileCheck --check-prefix=NO-GEP %s
4+
5+
target triple = "x86_64--linux-gnu"
6+
target datalayout = "e-m:e-p0:128:128-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
7+
; -p0:128:128 is added to ensure that transformation will be triggered.
8+
9+
define i128 @test(i128 %arg) {
10+
; GEP-LABEL: define i128 @test(
11+
; GEP-SAME: i128 [[ARG:%.*]]) {
12+
; GEP-NEXT: [[ENTRY:.*]]:
13+
; GEP-NEXT: [[CMP:%.*]] = icmp ugt i128 [[ARG]], 10
14+
; GEP-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
15+
; GEP: [[THEN]]:
16+
; GEP-NEXT: [[SUNKADDR:%.*]] = inttoptr i128 [[ARG]] to ptr
17+
; GEP-NEXT: [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[SUNKADDR]], i128 -32
18+
; GEP-NEXT: [[LOAD:%.*]] = load i128, ptr [[SUNKADDR1]], align 16
19+
; GEP-NEXT: br label %[[EXIT]]
20+
; GEP: [[EXIT]]:
21+
; GEP-NEXT: [[PHI:%.*]] = phi i128 [ [[LOAD]], %[[THEN]] ], [ 0, %[[ENTRY]] ]
22+
; GEP-NEXT: ret i128 [[PHI]]
23+
;
24+
; NO-GEP-LABEL: define i128 @test(
25+
; NO-GEP-SAME: i128 [[ARG:%.*]]) {
26+
; NO-GEP-NEXT: [[ENTRY:.*]]:
27+
; NO-GEP-NEXT: [[CMP:%.*]] = icmp ugt i128 [[ARG]], 10
28+
; NO-GEP-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
29+
; NO-GEP: [[THEN]]:
30+
; NO-GEP-NEXT: [[SUNKADDR:%.*]] = add i128 [[ARG]], -32
31+
; NO-GEP-NEXT: [[SUNKADDR1:%.*]] = inttoptr i128 [[SUNKADDR]] to ptr
32+
; NO-GEP-NEXT: [[LOAD:%.*]] = load i128, ptr [[SUNKADDR1]], align 16
33+
; NO-GEP-NEXT: br label %[[EXIT]]
34+
; NO-GEP: [[EXIT]]:
35+
; NO-GEP-NEXT: [[PHI:%.*]] = phi i128 [ [[LOAD]], %[[THEN]] ], [ 0, %[[ENTRY]] ]
36+
; NO-GEP-NEXT: ret i128 [[PHI]]
37+
;
38+
entry:
39+
%add = add i128 %arg, -32
40+
%cmp = icmp ugt i128 %arg, 10
41+
br i1 %cmp, label %then, label %exit
42+
43+
then:
44+
%inttoptr = inttoptr i128 %add to ptr
45+
%load = load i128, ptr %inttoptr, align 16
46+
br label %exit
47+
48+
exit:
49+
%phi = phi i128 [ %load, %then ], [ 0, %entry ]
50+
ret i128 %phi
51+
}
52+
53+
define void @test_combine(ptr %ptr, i128 %arg) {
54+
; GEP-LABEL: define void @test_combine(
55+
; GEP-SAME: ptr [[PTR:%.*]], i128 [[ARG:%.*]]) {
56+
; GEP-NEXT: [[ENTRY:.*:]]
57+
; GEP-NEXT: [[CMP:%.*]] = icmp ugt i128 [[ARG]], 10
58+
; GEP-NEXT: [[SELECT1:%.*]] = select i1 [[CMP]], i128 -32, i128 0
59+
; GEP-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i128 [[SELECT1]]
60+
; GEP-NEXT: store i128 1, ptr [[SUNKADDR]], align 16
61+
; GEP-NEXT: ret void
62+
;
63+
; NO-GEP-LABEL: define void @test_combine(
64+
; NO-GEP-SAME: ptr [[PTR:%.*]], i128 [[ARG:%.*]]) {
65+
; NO-GEP-NEXT: [[ENTRY:.*:]]
66+
; NO-GEP-NEXT: [[CMP:%.*]] = icmp ugt i128 [[ARG]], 10
67+
; NO-GEP-NEXT: [[SELECT1:%.*]] = select i1 [[CMP]], i128 -32, i128 0
68+
; NO-GEP-NEXT: [[SUNKADDR:%.*]] = ptrtoint ptr [[PTR]] to i128
69+
; NO-GEP-NEXT: [[SUNKADDR2:%.*]] = add i128 [[SUNKADDR]], [[SELECT1]]
70+
; NO-GEP-NEXT: [[SUNKADDR3:%.*]] = inttoptr i128 [[SUNKADDR2]] to ptr
71+
; NO-GEP-NEXT: store i128 1, ptr [[SUNKADDR3]], align 16
72+
; NO-GEP-NEXT: ret void
73+
;
74+
entry:
75+
%cmp = icmp ugt i128 %arg, 10
76+
%gep = getelementptr inbounds i8, ptr %ptr, i128 -32
77+
%select = select i1 %cmp, ptr %gep, ptr %ptr
78+
store i128 1, ptr %select, align 16
79+
ret void
80+
}
81+

0 commit comments

Comments
 (0)