Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions llvm/lib/Transforms/IPO/LowerTypeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ bool BitSetInfo::containsGlobalOffset(uint64_t Offset) const {
if (BitOffset >= BitSize)
return false;

return Bits.count(BitOffset);
return Bits.count(BitSize - 1 - BitOffset);
}

void BitSetInfo::print(raw_ostream &OS) const {
Expand Down Expand Up @@ -188,7 +188,11 @@ BitSetInfo BitSetBuilder::build() {
BSI.BitSize = ((Max - Min) >> BSI.AlignLog2) + 1;
for (uint64_t Offset : Offsets) {
Offset >>= BSI.AlignLog2;
BSI.Bits.insert(Offset);
// We invert the order of bits when adding them to the bitset. This is
// because the offset that we test against is computed by subtracting the
// address that we are testing from the global's address, which means that
// the offset increases as the tested address decreases.
BSI.Bits.insert(BSI.BitSize - 1 - Offset);
}

return BSI;
Expand Down Expand Up @@ -465,7 +469,8 @@ class LowerTypeTestsModule {
struct TypeIdLowering {
TypeTestResolution::Kind TheKind = TypeTestResolution::Unsat;

/// All except Unsat: the start address within the combined global.
/// All except Unsat: the address of the last element within the combined
/// global.
Constant *OffsetedGlobal;

/// ByteArray, Inline, AllOnes: log2 of the required global alignment
Expand Down Expand Up @@ -772,7 +777,11 @@ Value *LowerTypeTestsModule::lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
if (TIL.TheKind == TypeTestResolution::Single)
return B.CreateICmpEQ(PtrAsInt, OffsetedGlobalAsInt);

Value *PtrOffset = B.CreateSub(PtrAsInt, OffsetedGlobalAsInt);
// Here we compute `last element - address`. The reason why we do this instead
// of computing `address - first element` is that it leads to a slightly
// shorter instruction sequence on x86. Because it doesn't matter how we do
// the subtraction on other architectures, we do so unconditionally.
Value *PtrOffset = B.CreateSub(OffsetedGlobalAsInt, PtrAsInt);

// We need to check that the offset both falls within our range and is
// suitably aligned. We can check both properties at the same time by
Expand Down Expand Up @@ -1154,8 +1163,11 @@ void LowerTypeTestsModule::lowerTypeTestCalls(

ByteArrayInfo *BAI = nullptr;
TypeIdLowering TIL;

uint64_t GlobalOffset =
BSI.ByteOffset + ((BSI.BitSize - 1) << BSI.AlignLog2);
TIL.OffsetedGlobal = ConstantExpr::getGetElementPtr(
Int8Ty, CombinedGlobalAddr, ConstantInt::get(IntPtrTy, BSI.ByteOffset)),
Int8Ty, CombinedGlobalAddr, ConstantInt::get(IntPtrTy, GlobalOffset)),
TIL.AlignLog2 = ConstantInt::get(IntPtrTy, BSI.AlignLog2);
TIL.SizeM1 = ConstantInt::get(IntPtrTy, BSI.BitSize - 1);
if (BSI.isAllOnes()) {
Expand Down Expand Up @@ -2533,9 +2545,9 @@ PreservedAnalyses SimplifyTypeTestsPass::run(Module &M,
continue;
for (Use &U : make_early_inc_range(CE->uses())) {
auto *CE = dyn_cast<ConstantExpr>(U.getUser());
if (U.getOperandNo() == 1 && CE &&
if (U.getOperandNo() == 0 && CE &&
CE->getOpcode() == Instruction::Sub &&
MaySimplifyInt(CE->getOperand(0))) {
MaySimplifyInt(CE->getOperand(1))) {
// This is a computation of PtrOffset as generated by
// LowerTypeTestsModule::lowerTypeTestCall above. If
// isKnownTypeIdMember passes we just pretend it evaluated to 0. This
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ define i1 @foo(ptr %p) {
; AARCH64-LABEL: define i1 @foo
; AARCH64-SAME: (ptr [[P:%.*]]) {
; AARCH64-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
; AARCH64-NEXT: [[TMP2:%.*]] = sub i64 [[TMP1]], ptrtoint (ptr @.cfi.jumptable to i64)
; AARCH64-NEXT: [[TMP2:%.*]] = sub i64 ptrtoint (ptr getelementptr (i8, ptr @.cfi.jumptable, i64 8) to i64), [[TMP1]]
; AARCH64-NEXT: [[TMP3:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 3)
; AARCH64-NEXT: [[TMP4:%.*]] = icmp ule i64 [[TMP3]], 1
; AARCH64-NEXT: ret i1 [[TMP4]]
Expand Down
7 changes: 3 additions & 4 deletions llvm/test/Transforms/LowerTypeTests/asm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

define void @call(ptr %p) {
; CHECK: movl $__typeid_allones7_global_addr, %eax
; CHECK-NEXT: movq %rdi, %rcx
; CHECK-NEXT: subq %rax, %rcx
; CHECK-NEXT: rorq $__typeid_allones7_align, %rcx
; CHECK-NEXT: cmpq $__typeid_allones7_size_m1@ABS8, %rcx
; CHECK-NEXT: subq %rdi, %rax
; CHECK-NEXT: rorq $__typeid_allones7_align, %rax
; CHECK-NEXT: cmpq $__typeid_allones7_size_m1@ABS8, %rax
%x = call i1 @llvm.type.test(ptr %p, metadata !"allones7")
br i1 %x, label %t, label %f

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/LowerTypeTests/export-allones.ll
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,11 @@

; CHECK: [[G:@[0-9]+]] = private constant { [2048 x i8] } zeroinitializer

; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[G]]
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 2)
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i64 1 to ptr)
; X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 1 to ptr)

; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 4)
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 516)
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i64 2 to ptr)
; X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 128 to ptr)

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/LowerTypeTests/export-bytearray.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
; CHECK: [[G:@[0-9]+]] = private constant { [2048 x i8] } zeroinitializer
; CHECK: [[B:@[0-9]+]] = private constant [258 x i8] c"\03\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01"

; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[G]]
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 130)
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i64 1 to ptr)
; X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 65 to ptr)
; CHECK: @__typeid_typeid1_byte_array = hidden alias i8, ptr @bits.1
; X86: @__typeid_typeid1_bit_mask = hidden alias i8, inttoptr (i8 2 to ptr)

; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 4)
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 1032)
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i64 2 to ptr)
; X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 257 to ptr)
; CHECK: @__typeid_typeid2_byte_array = hidden alias i8, ptr @bits
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/LowerTypeTests/export-icall.ll
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ define void @f3(i32 %x) !type !8 {
!8 = !{i64 0, !"typeid3"}


; CHECK-DAG: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[JT1:.*]]
; CHECK-DAG: @__typeid_typeid1_global_addr = hidden alias i8, getelementptr (i8, ptr [[JT1:.*]], i64 32)
; CHECK-DAG: @__typeid_typeid1_align = hidden alias i8, inttoptr (i64 3 to ptr)
; CHECK-DAG: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 4 to ptr)

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/LowerTypeTests/export-inline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

; CHECK: [[G:@[0-9]+]] = private constant { [2048 x i8] } zeroinitializer

; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[G]]
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 6)
; CHECK-X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i8 1 to ptr)
; CHECK-X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 3 to ptr)
; CHECK-X86: @__typeid_typeid1_inline_bits = hidden alias i8, inttoptr (i32 9 to ptr)

; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 4)
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 136)
; CHECK-X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i8 2 to ptr)
; CHECK-X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 33 to ptr)
; CHECK-X86: @__typeid_typeid2_inline_bits = hidden alias i8, inttoptr (i64 8589934593 to ptr)
Expand Down
42 changes: 20 additions & 22 deletions llvm/test/Transforms/LowerTypeTests/function.ll
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
; RUN: opt -S -passes=lowertypetests -mtriple=i686-unknown-linux-gnu %s | FileCheck --check-prefixes=X86,X86-LINUX,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=x86_64-unknown-linux-gnu %s | FileCheck --check-prefixes=X86,X86-LINUX,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=i686-pc-win32 %s | FileCheck --check-prefixes=X86,X86-WIN32,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=x86_64-pc-win32 %s | FileCheck --check-prefixes=X86,X86-WIN32,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=riscv32-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=riscv64-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=i686-unknown-linux-gnu %s | FileCheck --check-prefixes=X86,X86-LINUX,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=x86_64-unknown-linux-gnu %s | FileCheck --check-prefixes=X86,X86-LINUX,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=i686-pc-win32 %s | FileCheck --check-prefixes=X86,X86-WIN32,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=x86_64-pc-win32 %s | FileCheck --check-prefixes=X86,X86-WIN32,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=riscv32-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=riscv64-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE,JT8 %s
; RUN: opt -S -passes=lowertypetests -mtriple=wasm32-unknown-unknown %s | FileCheck --check-prefix=WASM32 %s
; RUN: opt -S -passes=lowertypetests -mtriple=loongarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=LOONGARCH64,NATIVE %s
; RUN: opt -S -passes=lowertypetests -mtriple=loongarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=LOONGARCH64,NATIVE,JT8 %s

; The right format for Arm jump tables depends on the selected
; subtarget, so we can't get these tests right without the Arm target
; compiled in.
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=arm-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv7m-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMB,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv8m.base-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMB,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv6m-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMBV6M,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv5-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=aarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=arm-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE,JT4 %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv7m-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMB,NATIVE,JT4 %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv8m.base-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMB,NATIVE,JT4 %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv6m-unknown-linux-gnu %s | FileCheck --check-prefixes=THUMBV6M,NATIVE,JT16 %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=thumbv5-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE,JT4 %s %}
; RUN: %if arm-registered-target %{ opt -S -passes=lowertypetests -mtriple=aarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=ARM,NATIVE,JT4 %s %}

; Tests that we correctly handle bitsets containing 2 or more functions.

Expand Down Expand Up @@ -54,20 +54,18 @@ define internal void @g() !type !0 {
declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) noinline readnone

define i1 @foo(ptr %p) {
; NATIVE: sub i64 {{.*}}, ptrtoint (ptr @[[JT]] to i64)
; WASM32: sub i64 {{.*}}, ptrtoint (ptr getelementptr (i8, ptr null, i64 1) to i64)
; JT4: sub i64 ptrtoint (ptr getelementptr (i8, ptr @[[JT]], i64 4) to i64), {{.*}}
; JT8: sub i64 ptrtoint (ptr getelementptr (i8, ptr @[[JT]], i64 8) to i64), {{.*}}
; JT16: sub i64 ptrtoint (ptr getelementptr (i8, ptr @[[JT]], i64 16) to i64), {{.*}}
; WASM32: sub i64 ptrtoint (ptr getelementptr (i8, ptr null, i64 2) to i64), {{.*}}
; WASM32: icmp ule i64 {{.*}}, 1
%x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
ret i1 %x
}

; X86-LINUX: define private void @[[JT]]() #[[ATTR:.*]] align 8 {
; X86-WIN32: define private void @[[JT]]() #[[ATTR:.*]] align 8 {
; ARM: define private void @[[JT]]() #[[ATTR:.*]] align 4 {
; THUMB: define private void @[[JT]]() #[[ATTR:.*]] align 4 {
; THUMBV6M: define private void @[[JT]]() #[[ATTR:.*]] align 16 {
; RISCV: define private void @[[JT]]() #[[ATTR:.*]] align 8 {
; LOONGARCH64: define private void @[[JT]]() #[[ATTR:.*]] align 8 {
; JT4: define private void @[[JT]]() #[[ATTR:.*]] align 4 {
; JT8: define private void @[[JT]]() #[[ATTR:.*]] align 8 {
; JT16: define private void @[[JT]]() #[[ATTR:.*]] align 16 {

; X86: jmp ${0:c}@plt
; X86-SAME: int3
Expand Down
Loading
Loading