1; RUN: opt -lower-expect -strip-dead-prototypes -S -o - < %s | FileCheck %s 2; RUN: opt -S -passes='function(lower-expect),strip-dead-prototypes' < %s | FileCheck %s 3 4; CHECK-LABEL: @test1( 5define i32 @test1(i32 %x) nounwind uwtable ssp { 6entry: 7 %retval = alloca i32, align 4 8 %x.addr = alloca i32, align 4 9 store i32 %x, i32* %x.addr, align 4 10 %tmp = load i32, i32* %x.addr, align 4 11 %cmp = icmp sgt i32 %tmp, 1 12 %conv = zext i1 %cmp to i32 13 %conv1 = sext i32 %conv to i64 14 %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) 15 %tobool = icmp ne i64 %expval, 0 16; CHECK: !prof !0 17; CHECK-NOT: @llvm.expect 18 br i1 %tobool, label %if.then, label %if.end 19 20if.then: ; preds = %entry 21 %call = call i32 (...) @f() 22 store i32 %call, i32* %retval 23 br label %return 24 25if.end: ; preds = %entry 26 store i32 1, i32* %retval 27 br label %return 28 29return: ; preds = %if.end, %if.then 30 %0 = load i32, i32* %retval 31 ret i32 %0 32} 33 34declare i64 @llvm.expect.i64(i64, i64) nounwind readnone 35 36declare i32 @f(...) 37 38; CHECK-LABEL: @test2( 39define i32 @test2(i32 %x) nounwind uwtable ssp { 40entry: 41 %retval = alloca i32, align 4 42 %x.addr = alloca i32, align 4 43 store i32 %x, i32* %x.addr, align 4 44 %tmp = load i32, i32* %x.addr, align 4 45 %conv = sext i32 %tmp to i64 46 %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1) 47 %tobool = icmp ne i64 %expval, 0 48; CHECK: !prof !0 49; CHECK-NOT: @llvm.expect 50 br i1 %tobool, label %if.then, label %if.end 51 52if.then: ; preds = %entry 53 %call = call i32 (...) @f() 54 store i32 %call, i32* %retval 55 br label %return 56 57if.end: ; preds = %entry 58 store i32 1, i32* %retval 59 br label %return 60 61return: ; preds = %if.end, %if.then 62 %0 = load i32, i32* %retval 63 ret i32 %0 64} 65 66; CHECK-LABEL: @test3( 67define i32 @test3(i32 %x) nounwind uwtable ssp { 68entry: 69 %retval = alloca i32, align 4 70 %x.addr = alloca i32, align 4 71 store i32 %x, i32* %x.addr, align 4 72 %tmp = load i32, i32* %x.addr, align 4 73 %tobool = icmp ne i32 %tmp, 0 74 %lnot = xor i1 %tobool, true 75 %lnot.ext = zext i1 %lnot to i32 76 %conv = sext i32 %lnot.ext to i64 77 %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1) 78 %tobool1 = icmp ne i64 %expval, 0 79; CHECK: !prof !0 80; CHECK-NOT: @llvm.expect 81 br i1 %tobool1, label %if.then, label %if.end 82 83if.then: ; preds = %entry 84 %call = call i32 (...) @f() 85 store i32 %call, i32* %retval 86 br label %return 87 88if.end: ; preds = %entry 89 store i32 1, i32* %retval 90 br label %return 91 92return: ; preds = %if.end, %if.then 93 %0 = load i32, i32* %retval 94 ret i32 %0 95} 96 97; CHECK-LABEL: @test4( 98define i32 @test4(i32 %x) nounwind uwtable ssp { 99entry: 100 %retval = alloca i32, align 4 101 %x.addr = alloca i32, align 4 102 store i32 %x, i32* %x.addr, align 4 103 %tmp = load i32, i32* %x.addr, align 4 104 %tobool = icmp ne i32 %tmp, 0 105 %lnot = xor i1 %tobool, true 106 %lnot1 = xor i1 %lnot, true 107 %lnot.ext = zext i1 %lnot1 to i32 108 %conv = sext i32 %lnot.ext to i64 109 %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1) 110 %tobool2 = icmp ne i64 %expval, 0 111; CHECK: !prof !0 112; CHECK-NOT: @llvm.expect 113 br i1 %tobool2, label %if.then, label %if.end 114 115if.then: ; preds = %entry 116 %call = call i32 (...) @f() 117 store i32 %call, i32* %retval 118 br label %return 119 120if.end: ; preds = %entry 121 store i32 1, i32* %retval 122 br label %return 123 124return: ; preds = %if.end, %if.then 125 %0 = load i32, i32* %retval 126 ret i32 %0 127} 128 129; CHECK-LABEL: @test5( 130define i32 @test5(i32 %x) nounwind uwtable ssp { 131entry: 132 %retval = alloca i32, align 4 133 %x.addr = alloca i32, align 4 134 store i32 %x, i32* %x.addr, align 4 135 %tmp = load i32, i32* %x.addr, align 4 136 %cmp = icmp slt i32 %tmp, 0 137 %conv = zext i1 %cmp to i32 138 %conv1 = sext i32 %conv to i64 139 %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 0) 140 %tobool = icmp ne i64 %expval, 0 141; CHECK: !prof !1 142; CHECK-NOT: @llvm.expect 143 br i1 %tobool, label %if.then, label %if.end 144 145if.then: ; preds = %entry 146 %call = call i32 (...) @f() 147 store i32 %call, i32* %retval 148 br label %return 149 150if.end: ; preds = %entry 151 store i32 1, i32* %retval 152 br label %return 153 154return: ; preds = %if.end, %if.then 155 %0 = load i32, i32* %retval 156 ret i32 %0 157} 158 159; CHECK-LABEL: @test6( 160define i32 @test6(i32 %x) nounwind uwtable ssp { 161entry: 162 %retval = alloca i32, align 4 163 %x.addr = alloca i32, align 4 164 store i32 %x, i32* %x.addr, align 4 165 %tmp = load i32, i32* %x.addr, align 4 166 %conv = sext i32 %tmp to i64 167 %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1) 168; CHECK: !prof !2 169; CHECK-NOT: @llvm.expect 170 switch i64 %expval, label %sw.epilog [ 171 i64 1, label %sw.bb 172 i64 2, label %sw.bb 173 ] 174 175sw.bb: ; preds = %entry, %entry 176 store i32 0, i32* %retval 177 br label %return 178 179sw.epilog: ; preds = %entry 180 store i32 1, i32* %retval 181 br label %return 182 183return: ; preds = %sw.epilog, %sw.bb 184 %0 = load i32, i32* %retval 185 ret i32 %0 186} 187 188; CHECK-LABEL: @test7( 189define i32 @test7(i32 %x) nounwind uwtable ssp { 190entry: 191 %retval = alloca i32, align 4 192 %x.addr = alloca i32, align 4 193 store i32 %x, i32* %x.addr, align 4 194 %tmp = load i32, i32* %x.addr, align 4 195 %conv = sext i32 %tmp to i64 196 %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1) 197; CHECK: !prof !3 198; CHECK-NOT: @llvm.expect 199 switch i64 %expval, label %sw.epilog [ 200 i64 2, label %sw.bb 201 i64 3, label %sw.bb 202 ] 203 204sw.bb: ; preds = %entry, %entry 205 %tmp1 = load i32, i32* %x.addr, align 4 206 store i32 %tmp1, i32* %retval 207 br label %return 208 209sw.epilog: ; preds = %entry 210 store i32 0, i32* %retval 211 br label %return 212 213return: ; preds = %sw.epilog, %sw.bb 214 %0 = load i32, i32* %retval 215 ret i32 %0 216} 217 218; CHECK-LABEL: @test8( 219define i32 @test8(i32 %x) nounwind uwtable ssp { 220entry: 221 %retval = alloca i32, align 4 222 %x.addr = alloca i32, align 4 223 store i32 %x, i32* %x.addr, align 4 224 %tmp = load i32, i32* %x.addr, align 4 225 %cmp = icmp sgt i32 %tmp, 1 226 %conv = zext i1 %cmp to i32 227 %expval = call i32 @llvm.expect.i32(i32 %conv, i32 1) 228 %tobool = icmp ne i32 %expval, 0 229; CHECK: !prof !0 230; CHECK-NOT: @llvm.expect 231 br i1 %tobool, label %if.then, label %if.end 232 233if.then: ; preds = %entry 234 %call = call i32 (...) @f() 235 store i32 %call, i32* %retval 236 br label %return 237 238if.end: ; preds = %entry 239 store i32 1, i32* %retval 240 br label %return 241 242return: ; preds = %if.end, %if.then 243 %0 = load i32, i32* %retval 244 ret i32 %0 245} 246 247declare i32 @llvm.expect.i32(i32, i32) nounwind readnone 248 249; CHECK-LABEL: @test9( 250define i32 @test9(i32 %x) nounwind uwtable ssp { 251entry: 252 %retval = alloca i32, align 4 253 %x.addr = alloca i32, align 4 254 store i32 %x, i32* %x.addr, align 4 255 %tmp = load i32, i32* %x.addr, align 4 256 %cmp = icmp sgt i32 %tmp, 1 257 %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1) 258; CHECK: !prof !0 259; CHECK-NOT: @llvm.expect 260 br i1 %expval, label %if.then, label %if.end 261 262if.then: ; preds = %entry 263 %call = call i32 (...) @f() 264 store i32 %call, i32* %retval 265 br label %return 266 267if.end: ; preds = %entry 268 store i32 1, i32* %retval 269 br label %return 270 271return: ; preds = %if.end, %if.then 272 %0 = load i32, i32* %retval 273 ret i32 %0 274} 275 276; CHECK-LABEL: @test10( 277define i32 @test10(i64 %t6) { 278 %t7 = call i64 @llvm.expect.i64(i64 %t6, i64 0) 279 %t8 = icmp ne i64 %t7, 0 280 %t9 = select i1 %t8, i32 1, i32 2 281; CHECK: select{{.*}}, !prof !1 282 ret i32 %t9 283} 284 285 286declare i1 @llvm.expect.i1(i1, i1) nounwind readnone 287 288; CHECK: !0 = !{!"branch_weights", i32 2000, i32 1} 289; CHECK: !1 = !{!"branch_weights", i32 1, i32 2000} 290; CHECK: !2 = !{!"branch_weights", i32 1, i32 2000, i32 1} 291; CHECK: !3 = !{!"branch_weights", i32 2000, i32 1, i32 1} 292