1; Test that the ffs* library call simplifier works correctly. 2; 3; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC 4; RUN: opt < %s -instcombine -mtriple i386-pc-linux -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 5; RUN: opt < %s -instcombine -mtriple=arm64-apple-ios9.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 6; RUN: opt < %s -instcombine -mtriple=arm64-apple-tvos9.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 7; RUN: opt < %s -instcombine -mtriple=thumbv7k-apple-watchos2.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 8; RUN: opt < %s -instcombine -mtriple=x86_64-apple-macosx10.11 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 9; RUN: opt < %s -instcombine -mtriple=x86_64-freebsd-gnu -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET 10 11declare i32 @ffs(i32) 12declare i32 @ffsl(i32) 13declare i32 @ffsll(i64) 14 15; Check ffs(0) -> 0. 16 17define i32 @test_simplify1() { 18; ALL-LABEL: @test_simplify1( 19; ALL-NEXT: ret i32 0 20; 21 %ret = call i32 @ffs(i32 0) 22 ret i32 %ret 23} 24 25define i32 @test_simplify2() { 26; GENERIC-LABEL: @test_simplify2( 27; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsl(i32 0) 28; GENERIC-NEXT: ret i32 [[RET]] 29; 30; TARGET-LABEL: @test_simplify2( 31; TARGET-NEXT: ret i32 0 32; 33 %ret = call i32 @ffsl(i32 0) 34 ret i32 %ret 35} 36 37define i32 @test_simplify3() { 38; GENERIC-LABEL: @test_simplify3( 39; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 0) 40; GENERIC-NEXT: ret i32 [[RET]] 41; 42; TARGET-LABEL: @test_simplify3( 43; TARGET-NEXT: ret i32 0 44; 45 %ret = call i32 @ffsll(i64 0) 46 ret i32 %ret 47} 48 49; Check ffs(c) -> cttz(c) + 1, where 'c' is a constant. 50 51define i32 @test_simplify4() { 52; ALL-LABEL: @test_simplify4( 53; ALL-NEXT: ret i32 1 54; 55 %ret = call i32 @ffs(i32 1) 56 ret i32 %ret 57} 58 59define i32 @test_simplify5() { 60; ALL-LABEL: @test_simplify5( 61; ALL-NEXT: ret i32 12 62; 63 %ret = call i32 @ffs(i32 2048) 64 ret i32 %ret 65} 66 67define i32 @test_simplify6() { 68; ALL-LABEL: @test_simplify6( 69; ALL-NEXT: ret i32 17 70; 71 %ret = call i32 @ffs(i32 65536) 72 ret i32 %ret 73} 74 75define i32 @test_simplify7() { 76; GENERIC-LABEL: @test_simplify7( 77; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsl(i32 65536) 78; GENERIC-NEXT: ret i32 [[RET]] 79; 80; TARGET-LABEL: @test_simplify7( 81; TARGET-NEXT: ret i32 17 82; 83 %ret = call i32 @ffsl(i32 65536) 84 ret i32 %ret 85} 86 87define i32 @test_simplify8() { 88; GENERIC-LABEL: @test_simplify8( 89; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 1024) 90; GENERIC-NEXT: ret i32 [[RET]] 91; 92; TARGET-LABEL: @test_simplify8( 93; TARGET-NEXT: ret i32 11 94; 95 %ret = call i32 @ffsll(i64 1024) 96 ret i32 %ret 97} 98 99define i32 @test_simplify9() { 100; GENERIC-LABEL: @test_simplify9( 101; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 65536) 102; GENERIC-NEXT: ret i32 [[RET]] 103; 104; TARGET-LABEL: @test_simplify9( 105; TARGET-NEXT: ret i32 17 106; 107 %ret = call i32 @ffsll(i64 65536) 108 ret i32 %ret 109} 110 111define i32 @test_simplify10() { 112; GENERIC-LABEL: @test_simplify10( 113; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 17179869184) 114; GENERIC-NEXT: ret i32 [[RET]] 115; 116; TARGET-LABEL: @test_simplify10( 117; TARGET-NEXT: ret i32 35 118; 119 %ret = call i32 @ffsll(i64 17179869184) 120 ret i32 %ret 121} 122 123define i32 @test_simplify11() { 124; GENERIC-LABEL: @test_simplify11( 125; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 281474976710656) 126; GENERIC-NEXT: ret i32 [[RET]] 127; 128; TARGET-LABEL: @test_simplify11( 129; TARGET-NEXT: ret i32 49 130; 131 %ret = call i32 @ffsll(i64 281474976710656) 132 ret i32 %ret 133} 134 135define i32 @test_simplify12() { 136; GENERIC-LABEL: @test_simplify12( 137; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 1152921504606846976) 138; GENERIC-NEXT: ret i32 [[RET]] 139; 140; TARGET-LABEL: @test_simplify12( 141; TARGET-NEXT: ret i32 61 142; 143 %ret = call i32 @ffsll(i64 1152921504606846976) 144 ret i32 %ret 145} 146 147; Check ffs(x) -> x != 0 ? (i32)llvm.cttz(x) + 1 : 0. 148 149define i32 @test_simplify13(i32 %x) { 150; ALL-LABEL: @test_simplify13( 151; ALL-NEXT: [[CTTZ:%.*]] = call i32 @llvm.cttz.i32(i32 %x, i1 true), !range !0 152; ALL-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1 153; ALL-NEXT: [[TMP2:%.*]] = icmp eq i32 %x, 0 154; ALL-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]] 155; ALL-NEXT: ret i32 [[TMP3]] 156; 157 %ret = call i32 @ffs(i32 %x) 158 ret i32 %ret 159} 160 161define i32 @test_simplify14(i32 %x) { 162; GENERIC-LABEL: @test_simplify14( 163; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsl(i32 %x) 164; GENERIC-NEXT: ret i32 [[RET]] 165; 166; TARGET-LABEL: @test_simplify14( 167; TARGET-NEXT: [[CTTZ:%.*]] = call i32 @llvm.cttz.i32(i32 %x, i1 true), !range !0 168; TARGET-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1 169; TARGET-NEXT: [[TMP2:%.*]] = icmp eq i32 %x, 0 170; TARGET-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]] 171; TARGET-NEXT: ret i32 [[TMP3]] 172; 173 %ret = call i32 @ffsl(i32 %x) 174 ret i32 %ret 175} 176 177define i32 @test_simplify15(i64 %x) { 178; GENERIC-LABEL: @test_simplify15( 179; GENERIC-NEXT: [[RET:%.*]] = call i32 @ffsll(i64 %x) 180; GENERIC-NEXT: ret i32 [[RET]] 181; 182; TARGET-LABEL: @test_simplify15( 183; TARGET-NEXT: [[CTTZ:%.*]] = call i64 @llvm.cttz.i64(i64 %x, i1 true), !range !1 184; TARGET-NEXT: [[TMP1:%.*]] = trunc i64 [[CTTZ]] to i32 185; TARGET-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 186; TARGET-NEXT: [[TMP3:%.*]] = icmp eq i64 %x, 0 187; TARGET-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]] 188; TARGET-NEXT: ret i32 [[TMP4]] 189; 190 %ret = call i32 @ffsll(i64 %x) 191 ret i32 %ret 192} 193 194