Skip to content

Commit 8c2d0b5

Browse files
committed
[WIP][IR][Constants] Use ptr addrspace(N) zeroinitializer to represent a zero-value pointer
1 parent 5e46103 commit 8c2d0b5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+326
-272
lines changed

llvm/include/llvm/IR/Constant.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ class Constant : public User {
189189

190190
LLVM_ABI static Constant *getNullValue(Type *Ty);
191191

192+
LLVM_ABI static Constant *getZeroValue(Type *Ty);
193+
192194
/// @returns the value for an integer or vector of integer constant of the
193195
/// given type that has all its bits set to true.
194196
/// Get the all ones value

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6575,7 +6575,7 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
65756575
if (auto *TETy = dyn_cast<TargetExtType>(Ty))
65766576
if (!TETy->hasProperty(TargetExtType::HasZeroInit))
65776577
return error(ID.Loc, "invalid type for null constant");
6578-
V = Constant::getNullValue(Ty);
6578+
V = Constant::getZeroValue(Ty);
65796579
return false;
65806580
case ValID::t_None:
65816581
if (!Ty->isTokenTy())

llvm/lib/IR/AsmWriter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,15 @@ static void writeConstantInternal(raw_ostream &Out, const Constant *CV,
18061806
}
18071807
}
18081808

1809+
// Use zeroinitializer for inttoptr(0) constant expression.
1810+
if (CE->getOpcode() == Instruction::IntToPtr) {
1811+
Constant *SrcCI = cast<Constant>(CE->getOperand(0));
1812+
if (SrcCI->isNullValue()) {
1813+
Out << "zeroinitializer";
1814+
return;
1815+
}
1816+
}
1817+
18091818
Out << CE->getOpcodeName();
18101819
writeOptimizationInfo(Out, CE);
18111820
Out << " (";

llvm/lib/IR/ConstantFold.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
126126
if (isa<PoisonValue>(V))
127127
return PoisonValue::get(DestTy);
128128

129+
// TODO: For the following two cases, we can fold the constant to a constant
130+
// according to the data layout.
131+
132+
// We can't fold inttoptr(0) to ConstantNullPointer.
133+
if (opc == Instruction::IntToPtr && V->isZeroValue())
134+
return nullptr;
135+
// We can't fold ptrtoint(nullptr) to null.
136+
if (opc == Instruction::PtrToInt && V->isNullValue())
137+
return nullptr;
138+
129139
if (isa<UndefValue>(V)) {
130140
// zext(undef) = 0, because the top bits will be zero.
131141
// sext(undef) = 0, because the top bits will all be the same.

llvm/lib/IR/Constants.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,21 @@ bool Constant::isNegativeZeroValue() const {
7272
}
7373

7474
// Return true iff this constant is positive zero (floating point), negative
75-
// zero (floating point), or a null value.
75+
// zero (floating point), zero-value pointer, or a null value.
7676
bool Constant::isZeroValue() const {
7777
// Floating point values have an explicit -0.0 value.
7878
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
7979
return CFP->isZero();
8080

81+
// Zero value pointer is a constant expression of inttoptr(0).
82+
if (const auto *CE = dyn_cast<ConstantExpr>(this)) {
83+
if (CE->getOpcode() == Instruction::IntToPtr) {
84+
Constant *SrcCI = cast<Constant>(CE->getOperand(0));
85+
if (SrcCI->isZeroValue())
86+
return true;
87+
}
88+
}
89+
8190
// Check for constant splat vectors of 1 values.
8291
if (getType()->isVectorTy())
8392
if (const auto *SplatCFP = dyn_cast_or_null<ConstantFP>(getSplatValue()))
@@ -369,7 +378,10 @@ bool Constant::containsConstantExpression() const {
369378
return false;
370379
}
371380

372-
/// Constructor to create a '0' constant of arbitrary type.
381+
/// Constructor that creates a null constant of any type. For most types, this
382+
/// means a constant with value '0', but for pointer types, it represents a
383+
/// nullptr constant. A nullptr isn't always a zero-value pointer in certain
384+
/// address spaces on some targets.
373385
Constant *Constant::getNullValue(Type *Ty) {
374386
switch (Ty->getTypeID()) {
375387
case Type::IntegerTyID:
@@ -400,6 +412,19 @@ Constant *Constant::getNullValue(Type *Ty) {
400412
}
401413
}
402414

415+
/// Constructor that creates a zero constant of any type. For most types, this
416+
/// is equivalent to getNullValue. For pointer types, it creates an inttoptr
417+
/// constant expression.
418+
Constant *Constant::getZeroValue(Type *Ty) {
419+
switch (Ty->getTypeID()) {
420+
case Type::PointerTyID:
421+
return ConstantExpr::getIntToPtr(
422+
ConstantInt::get(Type::getInt8Ty(Ty->getContext()), 0), Ty);
423+
default:
424+
return Constant::getNullValue(Ty);
425+
}
426+
}
427+
403428
Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) {
404429
Type *ScalarTy = Ty->getScalarType();
405430

@@ -735,7 +760,7 @@ static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) {
735760
ReplaceableMetadataImpl::SalvageDebugInfo(*C);
736761
const_cast<Constant *>(C)->destroyConstant();
737762
}
738-
763+
739764
return true;
740765
}
741766

llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,23 +193,23 @@ define i32 @ptrtoint_very_short() {
193193
define <2 x i160> @ptrtoint_vec() {
194194
; CHECK-LABEL: define <2 x i160> @ptrtoint_vec
195195
; CHECK-SAME: () #[[ATTR0]] {
196-
; CHECK-NEXT: ret <2 x i160> zeroinitializer
196+
; CHECK-NEXT: ret <2 x i160> ptrtoint (<2 x ptr addrspace(7)> zeroinitializer to <2 x i160>)
197197
;
198198
ret <2 x i160> ptrtoint (<2 x ptr addrspace(7)> zeroinitializer to <2 x i160>)
199199
}
200200

201201
define ptr addrspace(7) @inttoptr() {
202202
; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr
203203
; CHECK-SAME: () #[[ATTR0]] {
204-
; CHECK-NEXT: ret { ptr addrspace(8), i32 } zeroinitializer
204+
; CHECK-NEXT: ret { ptr addrspace(8), i32 } { ptr addrspace(8) zeroinitializer, i32 0 }
205205
;
206206
ret ptr addrspace(7) inttoptr (i160 0 to ptr addrspace(7))
207207
}
208208

209209
define <2 x ptr addrspace(7)> @inttoptr_vec() {
210210
; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @inttoptr_vec
211211
; CHECK-SAME: () #[[ATTR0]] {
212-
; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } { <2 x ptr addrspace(8)> zeroinitializer, <2 x i32> <i32 1, i32 2> }
212+
; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } { <2 x ptr addrspace(8)> <ptr addrspace(8) zeroinitializer, ptr addrspace(8) zeroinitializer>, <2 x i32> <i32 1, i32 2> }
213213
;
214214
ret <2 x ptr addrspace(7)> inttoptr (<2 x i160> <i160 1, i160 2> to <2 x ptr addrspace(7)>)
215215
}

llvm/test/CodeGen/AMDGPU/remove-incompatible-s-time.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
]
3434

3535
; REALTIME: @ConstantExpr0 = internal global i64 ptrtoint (ptr @needs_s_memrealtime to i64)
36-
; NOREALTIME: @ConstantExpr0 = internal global i64 0
36+
; NOREALTIME: @ConstantExpr0 = internal global i64 ptrtoint (ptr null to i64)
3737
@ConstantExpr0 = internal global i64 ptrtoint (ptr @needs_s_memrealtime to i64)
3838

3939
; MEMTIME: @ConstantExpr1 = internal global i64 ptrtoint (ptr @needs_s_memtime to i64)
40-
; NOMEMTIME: @ConstantExpr1 = internal global i64 0
40+
; NOMEMTIME: @ConstantExpr1 = internal global i64 ptrtoint (ptr null to i64)
4141
@ConstantExpr1 = internal global i64 ptrtoint (ptr @needs_s_memtime to i64)
4242

4343
; REALTIME: define i64 @needs_s_memrealtime

llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ define void @test() #1 {
77
; CHECK-NEXT: [[ENTRY:.*:]]
88
; CHECK-NEXT: [[CTX_PG:%.*]] = alloca <vscale x 16 x i1>, align 2
99
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[CTX_PG]])
10-
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr inttoptr (i64 17592186044416 to ptr), align 1
10+
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 ptrtoint (ptr null to i64), 3
11+
; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP3]], 17592186044416
12+
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP4]] to ptr
13+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TMP2]], align 1
1114
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
12-
; CHECK-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB3:.*]]
13-
; CHECK: [[BB2]]:
14-
; CHECK-NEXT: call void @__asan_report_store8(i64 0) #[[ATTR4:[0-9]+]]
15+
; CHECK-NEXT: br i1 [[TMP1]], label %[[BB5:.*]], label %[[BB6:.*]]
16+
; CHECK: [[BB5]]:
17+
; CHECK-NEXT: call void @__asan_report_store8(i64 ptrtoint (ptr null to i64)) #[[ATTR4:[0-9]+]]
1518
; CHECK-NEXT: unreachable
16-
; CHECK: [[BB3]]:
19+
; CHECK: [[BB6]]:
1720
; CHECK-NEXT: store ptr [[CTX_PG]], ptr null, align 8
1821
; CHECK-NEXT: ret void
1922
;

llvm/test/Instrumentation/HWAddressSanitizer/RISCV/alloca.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ define void @test_alloca() sanitize_hwaddress !dbg !15 {
7070
; ZERO-BASED-SHADOW-LABEL: define void @test_alloca
7171
; ZERO-BASED-SHADOW-SAME: () #[[ATTR0:[0-9]+]] personality ptr @__hwasan_personality_thunk !dbg [[DBG8:![0-9]+]] {
7272
; ZERO-BASED-SHADOW-NEXT: entry:
73-
; ZERO-BASED-SHADOW-NEXT: [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
73+
; ZERO-BASED-SHADOW-NEXT: [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr zeroinitializer)
7474
; ZERO-BASED-SHADOW-NEXT: [[TMP0:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)
7575
; ZERO-BASED-SHADOW-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64
7676
; ZERO-BASED-SHADOW-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 20
@@ -143,7 +143,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
143143
;.
144144
; DYNAMIC-SHADOW: [[META0]] = !{ptr @hwasan.note}
145145
; DYNAMIC-SHADOW: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META2:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META3:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
146-
; DYNAMIC-SHADOW: [[META2]] = !DIFile(filename: "alloca.cpp", directory: {{.*}})
146+
; DYNAMIC-SHADOW: [[META2]] = !DIFile(filename: "{{.*}}alloca.cpp", directory: {{.*}})
147147
; DYNAMIC-SHADOW: [[META3]] = !{}
148148
; DYNAMIC-SHADOW: [[META4:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 4}
149149
; DYNAMIC-SHADOW: [[META5:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
@@ -160,7 +160,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
160160
;.
161161
; ZERO-BASED-SHADOW: [[META0]] = !{ptr @hwasan.note}
162162
; ZERO-BASED-SHADOW: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META2:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: [[META3:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
163-
; ZERO-BASED-SHADOW: [[META2]] = !DIFile(filename: "alloca.cpp", directory: {{.*}})
163+
; ZERO-BASED-SHADOW: [[META2]] = !DIFile(filename: "{{.*}}alloca.cpp", directory: {{.*}})
164164
; ZERO-BASED-SHADOW: [[META3]] = !{}
165165
; ZERO-BASED-SHADOW: [[META4:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 4}
166166
; ZERO-BASED-SHADOW: [[META5:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}

0 commit comments

Comments
 (0)