1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes='sroa<preserve-cfg>' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
; RUN: opt -passes='sroa<modify-cfg>' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
; This test checks that SROA does not introduce ptrtoint and inttoptr
; casts from and to non-integral pointers. The "ni:4" bit in the
; datalayout states that pointers of address space 4 are to be
; considered "non-integral".
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
target triple = "x86_64-unknown-linux-gnu"
define void @f0(i1 %alwaysFalse, i64 %val) {
; CHECK-LABEL: @f0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC:%.*]] = alloca i64, align 8
; CHECK-NEXT: store i64 [[VAL:%.*]], ptr [[LOC]], align 8
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[LOC_0_PTR:%.*]] = load ptr addrspace(4), ptr [[LOC]], align 8
; CHECK-NEXT: store i8 5, ptr addrspace(4) [[LOC_0_PTR]], align 1
; CHECK-NEXT: ret void
; CHECK: alwaysTaken:
; CHECK-NEXT: ret void
;
entry:
%loc = alloca i64
store i64 %val, ptr %loc
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%ptr = load ptr addrspace(4), ptr %loc
store i8 5, ptr addrspace(4) %ptr
ret void
alwaysTaken:
ret void
}
define i64 @f1(i1 %alwaysFalse, ptr addrspace(4) %val) {
; CHECK-LABEL: @f1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC:%.*]] = alloca ptr addrspace(4), align 8
; CHECK-NEXT: store ptr addrspace(4) [[VAL:%.*]], ptr [[LOC]], align 8
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[LOC_0_INT:%.*]] = load i64, ptr [[LOC]], align 8
; CHECK-NEXT: ret i64 [[LOC_0_INT]]
; CHECK: alwaysTaken:
; CHECK-NEXT: ret i64 42
;
entry:
%loc = alloca ptr addrspace(4)
store ptr addrspace(4) %val, ptr %loc
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%int = load i64, ptr %loc
ret i64 %int
alwaysTaken:
ret i64 42
}
define ptr addrspace(4) @memset(i1 %alwaysFalse) {
; CHECK-LABEL: @memset(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = alloca ptr addrspace(4), align 8
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[X]], i8 5, i64 8, i1 false)
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[X_0_X_FIELD_LD_0:%.*]] = load ptr addrspace(4), ptr [[X]], align 8
; CHECK-NEXT: ret ptr addrspace(4) [[X_0_X_FIELD_LD_0]]
; CHECK: alwaysTaken:
; CHECK-NEXT: ret ptr addrspace(4) null
;
entry:
%x = alloca ptr addrspace(4)
call void @llvm.memset.p0.i64(ptr align 8 %x, i8 5, i64 16, i1 false)
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%x.field.ld.0 = load ptr addrspace(4), ptr %x
ret ptr addrspace(4) %x.field.ld.0
alwaysTaken:
ret ptr addrspace(4) null
}
;; TODO: This one demonstrates a missed oppurtunity. The only known bit
;; pattern for a non-integral bit pattern is that null is zero. As such
;; we could do SROA and replace the memset w/a null store. This will
;; usually be gotten by instcombine.
define ptr addrspace(4) @memset_null(i1 %alwaysFalse) {
; CHECK-LABEL: @memset_null(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = alloca ptr addrspace(4), align 8
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[X]], i8 0, i64 8, i1 false)
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[X_0_X_FIELD_LD_0:%.*]] = load ptr addrspace(4), ptr [[X]], align 8
; CHECK-NEXT: ret ptr addrspace(4) [[X_0_X_FIELD_LD_0]]
; CHECK: alwaysTaken:
; CHECK-NEXT: ret ptr addrspace(4) null
;
entry:
%x = alloca ptr addrspace(4)
call void @llvm.memset.p0.i64(ptr align 8 %x, i8 0, i64 16, i1 false)
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%x.field.ld.0 = load ptr addrspace(4), ptr %x
ret ptr addrspace(4) %x.field.ld.0
alwaysTaken:
ret ptr addrspace(4) null
}
%union.anon = type { ptr }
define ptr@f2(ptr addrspace(4) %p) {
; CHECK-LABEL: @f2(
; CHECK-NEXT: [[DOTSROA_0:%.*]] = alloca ptr, align 8
; CHECK-NEXT: store ptr addrspace(4) [[P:%.*]], ptr [[DOTSROA_0]], align 8
; CHECK-NEXT: [[DOTSROA_0_0__SROA_0_0_:%.*]] = load ptr, ptr [[DOTSROA_0]], align 8
; CHECK-NEXT: ret ptr [[DOTSROA_0_0__SROA_0_0_]]
;
%1 = alloca %union.anon, align 8
store ptr addrspace(4) %p, ptr %1, align 8
%2 = load ptr, ptr %1, align 8
ret ptr %2
}
declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK-MODIFY-CFG: {{.*}}
; CHECK-PRESERVE-CFG: {{.*}}
|