1 ; RUN: opt < %s -instcombine -S | FileCheck %s 2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 target triple = "x86_64-unknown-linux-gnu" 4 5 ; Function Attrs: nounwind uwtable 6 define i32 @foo1(i32* %a) #0 { 7 entry: 8 %0 = load i32, i32* %a, align 4 9 10 ; Check that the alignment has been upgraded and that the assume has not 11 ; been removed: 12 ; CHECK-LABEL: @foo1 13 ; CHECK-DAG: load i32, i32* %a, align 32 14 ; CHECK-DAG: call void @llvm.assume 15 ; CHECK: ret i32 16 17 %ptrint = ptrtoint i32* %a to i64 18 %maskedptr = and i64 %ptrint, 31 19 %maskcond = icmp eq i64 %maskedptr, 0 20 tail call void @llvm.assume(i1 %maskcond) 21 22 ret i32 %0 23 } 24 25 ; Function Attrs: nounwind uwtable 26 define i32 @foo2(i32* %a) #0 { 27 entry: 28 ; Same check as in @foo1, but make sure it works if the assume is first too. 29 ; CHECK-LABEL: @foo2 30 ; CHECK-DAG: load i32, i32* %a, align 32 31 ; CHECK-DAG: call void @llvm.assume 32 ; CHECK: ret i32 33 34 %ptrint = ptrtoint i32* %a to i64 35 %maskedptr = and i64 %ptrint, 31 36 %maskcond = icmp eq i64 %maskedptr, 0 37 tail call void @llvm.assume(i1 %maskcond) 38 39 %0 = load i32, i32* %a, align 4 40 ret i32 %0 41 } 42 43 ; Function Attrs: nounwind 44 declare void @llvm.assume(i1) #1 45 46 define i32 @simple(i32 %a) #1 { 47 entry: 48 49 ; CHECK-LABEL: @simple 50 ; CHECK: call void @llvm.assume 51 ; CHECK: ret i32 4 52 53 %cmp = icmp eq i32 %a, 4 54 tail call void @llvm.assume(i1 %cmp) 55 ret i32 %a 56 } 57 58 ; Function Attrs: nounwind uwtable 59 define i32 @can1(i1 %a, i1 %b, i1 %c) { 60 entry: 61 %and1 = and i1 %a, %b 62 %and = and i1 %and1, %c 63 tail call void @llvm.assume(i1 %and) 64 65 ; CHECK-LABEL: @can1 66 ; CHECK: call void @llvm.assume(i1 %a) 67 ; CHECK: call void @llvm.assume(i1 %b) 68 ; CHECK: call void @llvm.assume(i1 %c) 69 ; CHECK: ret i32 70 71 ret i32 5 72 } 73 74 ; Function Attrs: nounwind uwtable 75 define i32 @can2(i1 %a, i1 %b, i1 %c) { 76 entry: 77 %v = or i1 %a, %b 78 %w = xor i1 %v, 1 79 tail call void @llvm.assume(i1 %w) 80 81 ; CHECK-LABEL: @can2 82 ; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true 83 ; CHECK: call void @llvm.assume(i1 %[[V1]]) 84 ; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true 85 ; CHECK: call void @llvm.assume(i1 %[[V2]]) 86 ; CHECK: ret i32 87 88 ret i32 5 89 } 90 91 define i32 @bar1(i32 %a) #0 { 92 entry: 93 %and1 = and i32 %a, 3 94 95 ; CHECK-LABEL: @bar1 96 ; CHECK: call void @llvm.assume 97 ; CHECK: ret i32 1 98 99 %and = and i32 %a, 7 100 %cmp = icmp eq i32 %and, 1 101 tail call void @llvm.assume(i1 %cmp) 102 103 ret i32 %and1 104 } 105 106 ; Function Attrs: nounwind uwtable 107 define i32 @bar2(i32 %a) #0 { 108 entry: 109 ; CHECK-LABEL: @bar2 110 ; CHECK: call void @llvm.assume 111 ; CHECK: ret i32 1 112 113 %and = and i32 %a, 7 114 %cmp = icmp eq i32 %and, 1 115 tail call void @llvm.assume(i1 %cmp) 116 117 %and1 = and i32 %a, 3 118 ret i32 %and1 119 } 120 121 ; Function Attrs: nounwind uwtable 122 define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 { 123 entry: 124 %and1 = and i32 %a, 3 125 126 ; Don't be fooled by other assumes around. 127 ; CHECK-LABEL: @bar3 128 ; CHECK: call void @llvm.assume 129 ; CHECK: ret i32 1 130 131 tail call void @llvm.assume(i1 %x) 132 133 %and = and i32 %a, 7 134 %cmp = icmp eq i32 %and, 1 135 tail call void @llvm.assume(i1 %cmp) 136 137 tail call void @llvm.assume(i1 %y) 138 139 ret i32 %and1 140 } 141 142 ; Function Attrs: nounwind uwtable 143 define i32 @bar4(i32 %a, i32 %b) { 144 entry: 145 %and1 = and i32 %b, 3 146 147 ; CHECK-LABEL: @bar4 148 ; CHECK: call void @llvm.assume 149 ; CHECK: call void @llvm.assume 150 ; CHECK: ret i32 1 151 152 %and = and i32 %a, 7 153 %cmp = icmp eq i32 %and, 1 154 tail call void @llvm.assume(i1 %cmp) 155 156 %cmp2 = icmp eq i32 %a, %b 157 tail call void @llvm.assume(i1 %cmp2) 158 159 ret i32 %and1 160 } 161 162 define i32 @icmp1(i32 %a) #0 { 163 entry: 164 %cmp = icmp sgt i32 %a, 5 165 tail call void @llvm.assume(i1 %cmp) 166 %conv = zext i1 %cmp to i32 167 ret i32 %conv 168 169 ; CHECK-LABEL: @icmp1 170 ; CHECK: call void @llvm.assume 171 ; CHECK: ret i32 1 172 173 } 174 175 ; Function Attrs: nounwind uwtable 176 define i32 @icmp2(i32 %a) #0 { 177 entry: 178 %cmp = icmp sgt i32 %a, 5 179 tail call void @llvm.assume(i1 %cmp) 180 %0 = zext i1 %cmp to i32 181 %lnot.ext = xor i32 %0, 1 182 ret i32 %lnot.ext 183 184 ; CHECK-LABEL: @icmp2 185 ; CHECK: call void @llvm.assume 186 ; CHECK: ret i32 0 187 } 188 189 declare void @escape(i32* %a) 190 191 ; Do we canonicalize a nonnull assumption on a load into 192 ; metadata form? 193 define i1 @nonnull1(i32** %a) { 194 entry: 195 %load = load i32*, i32** %a 196 %cmp = icmp ne i32* %load, null 197 tail call void @llvm.assume(i1 %cmp) 198 tail call void @escape(i32* %load) 199 %rval = icmp eq i32* %load, null 200 ret i1 %rval 201 202 ; CHECK-LABEL: @nonnull1 203 ; CHECK: !nonnull 204 ; CHECK-NOT: call void @llvm.assume 205 ; CHECK: ret i1 false 206 } 207 208 ; Make sure the above canonicalization applies only 209 ; to pointer types. Doing otherwise would be illegal. 210 define i1 @nonnull2(i32* %a) { 211 entry: 212 %load = load i32, i32* %a 213 %cmp = icmp ne i32 %load, 0 214 tail call void @llvm.assume(i1 %cmp) 215 %rval = icmp eq i32 %load, 0 216 ret i1 %rval 217 218 ; CHECK-LABEL: @nonnull2 219 ; CHECK-NOT: !nonnull 220 ; CHECK: call void @llvm.assume 221 } 222 223 ; Make sure the above canonicalization does not trigger 224 ; if the assume is control dependent on something else 225 define i1 @nonnull3(i32** %a, i1 %control) { 226 entry: 227 %load = load i32*, i32** %a 228 %cmp = icmp ne i32* %load, null 229 br i1 %control, label %taken, label %not_taken 230 taken: 231 tail call void @llvm.assume(i1 %cmp) 232 %rval = icmp eq i32* %load, null 233 ret i1 %rval 234 not_taken: 235 ret i1 true 236 237 ; CHECK-LABEL: @nonnull3 238 ; CHECK-NOT: !nonnull 239 ; CHECK: call void @llvm.assume 240 } 241 242 ; Make sure the above canonicalization does not trigger 243 ; if the path from the load to the assume is potentially 244 ; interrupted by an exception being thrown 245 define i1 @nonnull4(i32** %a) { 246 entry: 247 %load = load i32*, i32** %a 248 ;; This call may throw! 249 tail call void @escape(i32* %load) 250 %cmp = icmp ne i32* %load, null 251 tail call void @llvm.assume(i1 %cmp) 252 %rval = icmp eq i32* %load, null 253 ret i1 %rval 254 255 ; CHECK-LABEL: @nonnull4 256 ; CHECK-NOT: !nonnull 257 ; CHECK: call void @llvm.assume 258 } 259 260 261 262 263 attributes #0 = { nounwind uwtable } 264 attributes #1 = { nounwind } 265 266