1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s 3 4declare void @llvm.assume(i1) 5declare i8 @llvm.abs(i8, i1) 6 7; If we don't know anything about the argument, we can't do anything. 8 9define i8 @test0(i8 %x) { 10; CHECK-LABEL: @test0( 11; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false) 12; CHECK-NEXT: ret i8 [[R]] 13; 14 %r = call i8 @llvm.abs(i8 %x, i1 0) 15 ret i8 %r 16} 17define i8 @test1(i8 %x) { 18; CHECK-LABEL: @test1( 19; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true) 20; CHECK-NEXT: ret i8 [[R]] 21; 22 %r = call i8 @llvm.abs(i8 %x, i1 1) 23 ret i8 %r 24} 25 26; But if we know that the argument is always positive, we can bypass @llvm.abs. 27 28define i8 @test2(i8 %x) { 29; CHECK-LABEL: @test2( 30; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], -1 31; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 32; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 33; CHECK-NEXT: ret i8 [[R]] 34; 35 36 %lim = icmp sge i8 %x, -1 37 call void @llvm.assume(i1 %lim) 38 %r = call i8 @llvm.abs(i8 %x, i1 0) 39 ret i8 %r 40} 41define i8 @test3(i8 %x) { 42; CHECK-LABEL: @test3( 43; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], -1 44; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 45; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 46; CHECK-NEXT: ret i8 [[R]] 47; 48 49 %lim = icmp sge i8 %x, -1 50 call void @llvm.assume(i1 %lim) 51 %r = call i8 @llvm.abs(i8 %x, i1 1) 52 ret i8 %r 53} 54 55define i8 @test4(i8 %x) { 56; CHECK-LABEL: @test4( 57; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 0 58; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 59; CHECK-NEXT: ret i8 [[X]] 60; 61 62 %lim = icmp sge i8 %x, 0 63 call void @llvm.assume(i1 %lim) 64 %r = call i8 @llvm.abs(i8 %x, i1 0) 65 ret i8 %r 66} 67define i8 @test5(i8 %x) { 68; CHECK-LABEL: @test5( 69; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 0 70; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 71; CHECK-NEXT: ret i8 [[X]] 72; 73 74 %lim = icmp sge i8 %x, 0 75 call void @llvm.assume(i1 %lim) 76 %r = call i8 @llvm.abs(i8 %x, i1 1) 77 ret i8 %r 78} 79 80define i8 @test6(i8 %x) { 81; CHECK-LABEL: @test6( 82; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 1 83; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 84; CHECK-NEXT: ret i8 [[X]] 85; 86 87 %lim = icmp sge i8 %x, 1 88 call void @llvm.assume(i1 %lim) 89 %r = call i8 @llvm.abs(i8 %x, i1 0) 90 ret i8 %r 91} 92define i8 @test7(i8 %x) { 93; CHECK-LABEL: @test7( 94; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 1 95; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 96; CHECK-NEXT: ret i8 [[X]] 97; 98 99 %lim = icmp sge i8 %x, 1 100 call void @llvm.assume(i1 %lim) 101 %r = call i8 @llvm.abs(i8 %x, i1 1) 102 ret i8 %r 103} 104 105; Likewise, INT_MIN is fine for otherwise-positive value. 106 107define i8 @test8(i8 %x) { 108; CHECK-LABEL: @test8( 109; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 127 110; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 111; CHECK-NEXT: ret i8 [[X]] 112; 113 114 %lim = icmp ule i8 %x, 127 115 call void @llvm.assume(i1 %lim) 116 %r = call i8 @llvm.abs(i8 %x, i1 0) 117 ret i8 %r 118} 119define i8 @test9(i8 %x) { 120; CHECK-LABEL: @test9( 121; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 127 122; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 123; CHECK-NEXT: ret i8 [[X]] 124; 125 126 %lim = icmp ule i8 %x, 127 127 call void @llvm.assume(i1 %lim) 128 %r = call i8 @llvm.abs(i8 %x, i1 1) 129 ret i8 %r 130} 131 132define i8 @test10(i8 %x) { 133; CHECK-LABEL: @test10( 134; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], -128 135; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 136; CHECK-NEXT: ret i8 [[X]] 137; 138 139 %lim = icmp ule i8 %x, 128 140 call void @llvm.assume(i1 %lim) 141 %r = call i8 @llvm.abs(i8 %x, i1 0) 142 ret i8 %r 143} 144define i8 @test11(i8 %x) { 145; CHECK-LABEL: @test11( 146; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], -128 147; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 148; CHECK-NEXT: ret i8 [[X]] 149; 150 151 %lim = icmp ule i8 %x, 128 152 call void @llvm.assume(i1 %lim) 153 %r = call i8 @llvm.abs(i8 %x, i1 1) 154 ret i8 %r 155} 156 157define i8 @test12(i8 %x) { 158; CHECK-LABEL: @test12( 159; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], -127 160; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 161; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) 162; CHECK-NEXT: ret i8 [[R]] 163; 164 165 %lim = icmp ule i8 %x, 129 166 call void @llvm.assume(i1 %lim) 167 %r = call i8 @llvm.abs(i8 %x, i1 0) 168 ret i8 %r 169} 170define i8 @test13(i8 %x) { 171; CHECK-LABEL: @test13( 172; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], -127 173; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 174; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 175; CHECK-NEXT: ret i8 [[R]] 176; 177 178 %lim = icmp ule i8 %x, 129 179 call void @llvm.assume(i1 %lim) 180 %r = call i8 @llvm.abs(i8 %x, i1 1) 181 ret i8 %r 182} 183 184; Likewise, if we know that argument is always negative, 185; we can expand @llvm.abs into a direct negation. 186; For negative arguments, we must be careful to include 0 though. 187 188define i8 @test14(i8 %x) { 189; CHECK-LABEL: @test14( 190; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], -1 191; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 192; CHECK-NEXT: [[R1:%.*]] = sub i8 0, [[X]] 193; CHECK-NEXT: ret i8 [[R1]] 194; 195 196 %lim = icmp sle i8 %x, -1 197 call void @llvm.assume(i1 %lim) 198 %r = call i8 @llvm.abs(i8 %x, i1 0) 199 ret i8 %r 200} 201define i8 @test15(i8 %x) { 202; CHECK-LABEL: @test15( 203; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], -1 204; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 205; CHECK-NEXT: [[R1:%.*]] = sub nsw i8 0, [[X]] 206; CHECK-NEXT: ret i8 [[R1]] 207; 208 209 %lim = icmp sle i8 %x, -1 210 call void @llvm.assume(i1 %lim) 211 %r = call i8 @llvm.abs(i8 %x, i1 1) 212 ret i8 %r 213} 214 215define i8 @test16(i8 %x) { 216; CHECK-LABEL: @test16( 217; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 0 218; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 219; CHECK-NEXT: [[R1:%.*]] = sub i8 0, [[X]] 220; CHECK-NEXT: ret i8 [[R1]] 221; 222 223 %lim = icmp sle i8 %x, 0 224 call void @llvm.assume(i1 %lim) 225 %r = call i8 @llvm.abs(i8 %x, i1 0) 226 ret i8 %r 227} 228define i8 @test17(i8 %x) { 229; CHECK-LABEL: @test17( 230; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 0 231; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 232; CHECK-NEXT: [[R1:%.*]] = sub nsw i8 0, [[X]] 233; CHECK-NEXT: ret i8 [[R1]] 234; 235 236 %lim = icmp sle i8 %x, 0 237 call void @llvm.assume(i1 %lim) 238 %r = call i8 @llvm.abs(i8 %x, i1 1) 239 ret i8 %r 240} 241 242define i8 @test18(i8 %x) { 243; CHECK-LABEL: @test18( 244; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 1 245; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 246; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) 247; CHECK-NEXT: ret i8 [[R]] 248; 249 250 %lim = icmp sle i8 %x, 1 251 call void @llvm.assume(i1 %lim) 252 %r = call i8 @llvm.abs(i8 %x, i1 0) 253 ret i8 %r 254} 255define i8 @test19(i8 %x) { 256; CHECK-LABEL: @test19( 257; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 1 258; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 259; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 260; CHECK-NEXT: ret i8 [[R]] 261; 262 263 %lim = icmp sle i8 %x, 1 264 call void @llvm.assume(i1 %lim) 265 %r = call i8 @llvm.abs(i8 %x, i1 1) 266 ret i8 %r 267} 268 269; And again, INT_MIN is also fine for otherwise-negative range. 270 271define i8 @test20(i8 %x) { 272; CHECK-LABEL: @test20( 273; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 127 274; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 275; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) 276; CHECK-NEXT: ret i8 [[R]] 277; 278 279 %lim = icmp uge i8 %x, 127 280 call void @llvm.assume(i1 %lim) 281 %r = call i8 @llvm.abs(i8 %x, i1 0) 282 ret i8 %r 283} 284define i8 @test21(i8 %x) { 285; CHECK-LABEL: @test21( 286; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 127 287; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 288; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 289; CHECK-NEXT: ret i8 [[R]] 290; 291 292 %lim = icmp uge i8 %x, 127 293 call void @llvm.assume(i1 %lim) 294 %r = call i8 @llvm.abs(i8 %x, i1 1) 295 ret i8 %r 296} 297 298define i8 @test22(i8 %x) { 299; CHECK-LABEL: @test22( 300; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], -128 301; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 302; CHECK-NEXT: [[R1:%.*]] = sub i8 0, [[X]] 303; CHECK-NEXT: ret i8 [[R1]] 304; 305 306 %lim = icmp uge i8 %x, 128 307 call void @llvm.assume(i1 %lim) 308 %r = call i8 @llvm.abs(i8 %x, i1 0) 309 ret i8 %r 310} 311define i8 @test23(i8 %x) { 312; CHECK-LABEL: @test23( 313; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], -128 314; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 315; CHECK-NEXT: [[R1:%.*]] = sub nsw i8 0, [[X]] 316; CHECK-NEXT: ret i8 [[R1]] 317; 318 319 %lim = icmp uge i8 %x, 128 320 call void @llvm.assume(i1 %lim) 321 %r = call i8 @llvm.abs(i8 %x, i1 1) 322 ret i8 %r 323} 324 325define i8 @test24(i8 %x) { 326; CHECK-LABEL: @test24( 327; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], -127 328; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 329; CHECK-NEXT: [[R1:%.*]] = sub nsw i8 0, [[X]] 330; CHECK-NEXT: ret i8 [[R1]] 331; 332 333 %lim = icmp uge i8 %x, 129 334 call void @llvm.assume(i1 %lim) 335 %r = call i8 @llvm.abs(i8 %x, i1 0) 336 ret i8 %r 337} 338define i8 @test25(i8 %x) { 339; CHECK-LABEL: @test25( 340; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], -127 341; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 342; CHECK-NEXT: [[R1:%.*]] = sub nsw i8 0, [[X]] 343; CHECK-NEXT: ret i8 [[R1]] 344; 345 346 %lim = icmp uge i8 %x, 129 347 call void @llvm.assume(i1 %lim) 348 %r = call i8 @llvm.abs(i8 %x, i1 1) 349 ret i8 %r 350} 351 352; If all else fails, we can sometimes at least inferr NSW. 353 354define i8 @test26(i8 %x) { 355; CHECK-LABEL: @test26( 356; CHECK-NEXT: [[LIM:%.*]] = icmp ne i8 [[X:%.*]], -128 357; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 358; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 359; CHECK-NEXT: ret i8 [[R]] 360; 361 %lim = icmp ne i8 %x, 128 362 call void @llvm.assume(i1 %lim) 363 %r = call i8 @llvm.abs(i8 %x, i1 0) 364 ret i8 %r 365} 366define i8 @test27(i8 %x) { 367; CHECK-LABEL: @test27( 368; CHECK-NEXT: [[LIM:%.*]] = icmp ne i8 [[X:%.*]], -128 369; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) 370; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true) 371; CHECK-NEXT: ret i8 [[R]] 372; 373 %lim = icmp ne i8 %x, 128 374 call void @llvm.assume(i1 %lim) 375 %r = call i8 @llvm.abs(i8 %x, i1 1) 376 ret i8 %r 377} 378