1; RUN: opt < %s -instcombine -S | FileCheck %s 2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3target triple = "x86_64-unknown-linux-gnu" 4 5; Function Attrs: nounwind uwtable 6define i32 @foo1(i32* %a) #0 { 7entry: 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 26define i32 @foo2(i32* %a) #0 { 27entry: 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 44declare void @llvm.assume(i1) #1 45 46define i32 @simple(i32 %a) #1 { 47entry: 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 59define i32 @can1(i1 %a, i1 %b, i1 %c) { 60entry: 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 75define i32 @can2(i1 %a, i1 %b, i1 %c) { 76entry: 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 91define i32 @bar1(i32 %a) #0 { 92entry: 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 107define i32 @bar2(i32 %a) #0 { 108entry: 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 122define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 { 123entry: 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 143define i32 @bar4(i32 %a, i32 %b) { 144entry: 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 162define i32 @icmp1(i32 %a) #0 { 163entry: 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 176define i32 @icmp2(i32 %a) #0 { 177entry: 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 189declare void @escape(i32* %a) 190 191; Do we canonicalize a nonnull assumption on a load into 192; metadata form? 193define i1 @nonnull1(i32** %a) { 194entry: 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. 210define i1 @nonnull2(i32* %a) { 211entry: 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 225define i1 @nonnull3(i32** %a, i1 %control) { 226entry: 227 %load = load i32*, i32** %a 228 %cmp = icmp ne i32* %load, null 229 br i1 %control, label %taken, label %not_taken 230taken: 231 tail call void @llvm.assume(i1 %cmp) 232 %rval = icmp eq i32* %load, null 233 ret i1 %rval 234not_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 245define i1 @nonnull4(i32** %a) { 246entry: 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 263attributes #0 = { nounwind uwtable } 264attributes #1 = { nounwind } 265 266