Even if memory is valid from `llvm` point of view, e.g. local alloca, sanitizers have API for user specific memory annotations. These annotations can be used to track size of the local object, e.g. inline vectors may prevent accesses beyond the current vector size. So valid programs should not access those parts of alloca before checking preconditions. Fixes #100639.
102 lines
3.3 KiB
LLVM
102 lines
3.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-grtev4-linux-gnu"
|
|
|
|
define i32 @test_plain(i1 %f) {
|
|
; CHECK-LABEL: @test_plain(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]], align 8
|
|
; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]], align 8
|
|
; CHECK-NEXT: [[L:%.*]] = select i1 [[F:%.*]], i32 [[A_VAL]], i32 [[B_VAL]]
|
|
; CHECK-NEXT: ret i32 [[L]]
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 8
|
|
%b = alloca i32, align 8
|
|
%sel = select i1 %f, ptr %a, ptr %b
|
|
%l = load i32, ptr %sel, align 8
|
|
ret i32 %l
|
|
}
|
|
|
|
; Don't speculate as the condition may control which memory is valid from
|
|
; sanitizer perspective.
|
|
define i32 @test_asan(i1 %f) sanitize_address {
|
|
; CHECK-LABEL: @test_asan(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[F:%.*]], ptr [[A]], ptr [[B]]
|
|
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[SEL]], align 8
|
|
; CHECK-NEXT: ret i32 [[L]]
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 8
|
|
%b = alloca i32, align 8
|
|
%sel = select i1 %f, ptr %a, ptr %b
|
|
%l = load i32, ptr %sel, align 8
|
|
ret i32 %l
|
|
}
|
|
|
|
|
|
; Don't speculate as the condition may control which memory is valid from
|
|
; sanitizer perspective.
|
|
define i32 @test_hwasan(i1 %f) sanitize_hwaddress {
|
|
; CHECK-LABEL: @test_hwasan(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[F:%.*]], ptr [[A]], ptr [[B]]
|
|
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[SEL]], align 8
|
|
; CHECK-NEXT: ret i32 [[L]]
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 8
|
|
%b = alloca i32, align 8
|
|
%sel = select i1 %f, ptr %a, ptr %b
|
|
%l = load i32, ptr %sel, align 8
|
|
ret i32 %l
|
|
}
|
|
|
|
; Don't speculate as the condition may control which memory is valid from
|
|
; sanitizer perspective.
|
|
define i32 @test_tsan(i1 %f) sanitize_thread {
|
|
; CHECK-LABEL: @test_tsan(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[F:%.*]], ptr [[A]], ptr [[B]]
|
|
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[SEL]], align 8
|
|
; CHECK-NEXT: ret i32 [[L]]
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 8
|
|
%b = alloca i32, align 8
|
|
%sel = select i1 %f, ptr %a, ptr %b
|
|
%l = load i32, ptr %sel, align 8
|
|
ret i32 %l
|
|
}
|
|
|
|
; Msan just propagates shadow, even if speculated load accesses uninitialized
|
|
; value, instrumentation will select shadow of the desired value anyway.
|
|
define i32 @test_msan(i1 %f) sanitize_memory {
|
|
; CHECK-LABEL: @test_msan(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 8
|
|
; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]], align 8
|
|
; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]], align 8
|
|
; CHECK-NEXT: [[L:%.*]] = select i1 [[F:%.*]], i32 [[A_VAL]], i32 [[B_VAL]]
|
|
; CHECK-NEXT: ret i32 [[L]]
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 8
|
|
%b = alloca i32, align 8
|
|
%sel = select i1 %f, ptr %a, ptr %b
|
|
%l = load i32, ptr %sel, align 8
|
|
ret i32 %l
|
|
}
|