1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
Peter Collingbourne 855343fa29 hwasan: Compatibility fixes for short granules.
We can't use short granules with stack instrumentation when targeting older
API levels because the rest of the system won't understand the short granule
tags stored in shadow memory.

Moreover, we need to be able to let old binaries (which won't understand
short granule tags) run on a new system that supports short granule
tags. Such binaries will call the __hwasan_tag_mismatch function when their
outlined checks fail. We can compensate for the binary's lack of support
for short granules by implementing the short granule part of the check in
the __hwasan_tag_mismatch function. Unfortunately we can't do anything about
inline checks, but I don't believe that we can generate these by default on
aarch64, nor did we do so when the ABI was fixed.

A new function, __hwasan_tag_mismatch_v2, is introduced that lets code
targeting the new runtime avoid redoing the short granule check. Because tag
mismatches are rare this isn't important from a performance perspective; the
main benefit is that it introduces a symbol dependency that prevents binaries
targeting the new runtime from running on older (i.e. incompatible) runtimes.

Differential Revision: https://reviews.llvm.org/D68059

llvm-svn: 373035
2019-09-27 01:02:10 +00:00

423 lines
17 KiB
LLVM

; Test basic address sanitizer instrumentation.
;
; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-DYNAMIC-SHADOW
; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW
; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-ZERO-BASED-SHADOW
; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW
; Ensure than hwasan runs with the new PM pass
; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-DYNAMIC-SHADOW
; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW
; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ABORT-ZERO-BASED-SHADOW
; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW
; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @hwasan.module_ctor, i8* bitcast (void ()* @hwasan.module_ctor to i8*) }]
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-android10000"
define i8 @test_load8(i8* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load8(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label %[[MISMATCH:[0-9]*]], label %[[CONT:[0-9]*]], !prof {{.*}}
; RECOVER: [[MISMATCH]]:
; RECOVER: %[[NOTSHORT:[^ ]*]] = icmp ugt i8 %[[MEMTAG]], 15
; RECOVER: br i1 %[[NOTSHORT]], label %[[FAIL:[0-9]*]], label %[[SHORT:[0-9]*]], !prof {{.*}}
; RECOVER: [[FAIL]]:
; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
; RECOVER: br label
; RECOVER: [[SHORT]]:
; RECOVER: %[[LOWBITS:[^ ]*]] = and i64 %[[A]], 15
; RECOVER: %[[LOWBITS_I8:[^ ]*]] = trunc i64 %[[LOWBITS]] to i8
; RECOVER: %[[LAST:[^ ]*]] = add i8 %[[LOWBITS_I8]], 0
; RECOVER: %[[OOB:[^ ]*]] = icmp uge i8 %[[LAST]], %[[MEMTAG]]
; RECOVER: br i1 %[[OOB]], label %[[FAIL]], label %[[INBOUNDS:[0-9]*]], !prof {{.*}}
; RECOVER: [[INBOUNDS]]:
; RECOVER: %[[EOG_ADDR:[^ ]*]] = or i64 %[[C]], 15
; RECOVER: %[[EOG_PTR:[^ ]*]] = inttoptr i64 %[[EOG_ADDR]] to i8*
; RECOVER: %[[EOGTAG:[^ ]*]] = load i8, i8* %[[EOG_PTR]]
; RECOVER: %[[EOG_MISMATCH:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[EOGTAG]]
; RECOVER: br i1 %[[EOG_MISMATCH]], label %[[FAIL]], label %[[CONT1:[0-9]*]], !prof {{.*}}
; RECOVER: [[CONT1]]:
; RECOVER: br label %[[CONT]]
; RECOVER: [[CONT]]:
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %a, i32 0)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %a, i32 0)
; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
; CHECK: ret i8 %[[G]]
entry:
%b = load i8, i8* %a, align 4
ret i8 %b
}
define i16 @test_load16(i16* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load16(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label %[[MISMATCH:[0-9]*]], label %[[CONT:[0-9]*]], !prof {{.*}}
; RECOVER: [[MISMATCH]]:
; RECOVER: %[[NOTSHORT:[^ ]*]] = icmp ugt i8 %[[MEMTAG]], 15
; RECOVER: br i1 %[[NOTSHORT]], label %[[FAIL:[0-9]*]], label %[[SHORT:[0-9]*]], !prof {{.*}}
; RECOVER: [[FAIL]]:
; RECOVER: call void asm sideeffect "brk #2337", "{x0}"(i64 %[[A]])
; RECOVER: br label
; RECOVER: [[SHORT]]:
; RECOVER: %[[LOWBITS:[^ ]*]] = and i64 %[[A]], 15
; RECOVER: %[[LOWBITS_I8:[^ ]*]] = trunc i64 %[[LOWBITS]] to i8
; RECOVER: %[[LAST:[^ ]*]] = add i8 %[[LOWBITS_I8]], 1
; RECOVER: %[[OOB:[^ ]*]] = icmp uge i8 %[[LAST]], %[[MEMTAG]]
; RECOVER: br i1 %[[OOB]], label %[[FAIL]], label %[[INBOUNDS:[0-9]*]], !prof {{.*}}
; RECOVER: [[INBOUNDS]]:
; RECOVER: %[[EOG_ADDR:[^ ]*]] = or i64 %[[C]], 15
; RECOVER: %[[EOG_PTR:[^ ]*]] = inttoptr i64 %[[EOG_ADDR]] to i8*
; RECOVER: %[[EOGTAG:[^ ]*]] = load i8, i8* %[[EOG_PTR]]
; RECOVER: %[[EOG_MISMATCH:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[EOGTAG]]
; RECOVER: br i1 %[[EOG_MISMATCH]], label %[[FAIL]], label %[[CONT1:[0-9]*]], !prof {{.*}}
; RECOVER: [[CONT1]]:
; RECOVER: br label %[[CONT]]
; RECOVER: [[CONT]]:
; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 1)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 1)
; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4
; CHECK: ret i16 %[[G]]
entry:
%b = load i16, i16* %a, align 4
ret i16 %b
}
define i32 @test_load32(i32* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load32(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 2)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 2)
; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4
; CHECK: ret i32 %[[G]]
entry:
%b = load i32, i32* %a, align 4
ret i32 %b
}
define i64 @test_load64(i64* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load64(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2339", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 3)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 3)
; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8
; CHECK: ret i64 %[[G]]
entry:
%b = load i64, i64* %a, align 8
ret i64 %b
}
define i128 @test_load128(i128* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load128(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2340", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 4)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 4)
; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16
; CHECK: ret i128 %[[G]]
entry:
%b = load i128, i128* %a, align 16
ret i128 %b
}
define i40 @test_load40(i40* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load40(
; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
; ABORT: call void @__hwasan_loadN(i64 %[[A]], i64 5)
; RECOVER: call void @__hwasan_loadN_noabort(i64 %[[A]], i64 5)
; CHECK: %[[B:[^ ]*]] = load i40, i40* %a
; CHECK: ret i40 %[[B]]
entry:
%b = load i40, i40* %a, align 4
ret i40 %b
}
define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store8(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2352", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %a, i32 16)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %a, i32 16)
; CHECK: store i8 %b, i8* %a, align 4
; CHECK: ret void
entry:
store i8 %b, i8* %a, align 4
ret void
}
define void @test_store16(i16* %a, i16 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store16(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2353", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 17)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 17)
; CHECK: store i16 %b, i16* %a, align 4
; CHECK: ret void
entry:
store i16 %b, i16* %a, align 4
ret void
}
define void @test_store32(i32* %a, i32 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store32(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2354", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 18)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 18)
; CHECK: store i32 %b, i32* %a, align 4
; CHECK: ret void
entry:
store i32 %b, i32* %a, align 4
ret void
}
define void @test_store64(i64* %a, i64 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store64(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2355", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 19)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 19)
; CHECK: store i64 %b, i64* %a, align 8
; CHECK: ret void
entry:
store i64 %b, i64* %a, align 8
ret void
}
define void @test_store128(i128* %a, i128 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store128(
; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
; RECOVER: call void asm sideeffect "brk #2356", "{x0}"(i64 %[[A]])
; RECOVER: br label
; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
; ABORT-DYNAMIC-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 20)
; ABORT-ZERO-BASED-SHADOW: call void @llvm.hwasan.check.memaccess.shortgranules(i8* null, i8* %[[A]], i32 20)
; CHECK: store i128 %b, i128* %a, align 16
; CHECK: ret void
entry:
store i128 %b, i128* %a, align 16
ret void
}
define void @test_store40(i40* %a, i40 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store40(
; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 5)
; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 5)
; CHECK: store i40 %b, i40* %a
; CHECK: ret void
entry:
store i40 %b, i40* %a, align 4
ret void
}
define void @test_store_unaligned(i64* %a, i64 %b) sanitize_hwaddress {
; CHECK-LABEL: @test_store_unaligned(
; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 8)
; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 8)
; CHECK: store i64 %b, i64* %a, align 4
; CHECK: ret void
entry:
store i64 %b, i64* %a, align 4
ret void
}
define i8 @test_load_noattr(i8* %a) {
; CHECK-LABEL: @test_load_noattr(
; CHECK-NEXT: entry:
; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
; CHECK-NEXT: ret i8 %[[B]]
entry:
%b = load i8, i8* %a, align 4
ret i8 %b
}
define i8 @test_load_notmyattr(i8* %a) sanitize_address {
; CHECK-LABEL: @test_load_notmyattr(
; CHECK-NEXT: entry:
; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
; CHECK-NEXT: ret i8 %[[B]]
entry:
%b = load i8, i8* %a, align 4
ret i8 %b
}
define i8 @test_load_addrspace(i8 addrspace(256)* %a) sanitize_hwaddress {
; CHECK-LABEL: @test_load_addrspace(
; CHECK-NEXT: entry:
; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8 addrspace(256)* %a
; CHECK-NEXT: ret i8 %[[B]]
entry:
%b = load i8, i8 addrspace(256)* %a, align 4
ret i8 %b
}
; CHECK: declare void @__hwasan_init()
; CHECK: define internal void @hwasan.module_ctor() comdat {
; CHECK-NEXT: call void @__hwasan_init()
; CHECK-NEXT: ret void
; CHECK-NEXT: }