1*9880d681SAndroid Build Coastguard Worker; Test that the ffs* library call simplifier works correctly. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -mtriple i386-pc-linux -instcombine -S | FileCheck %s -check-prefix=CHECK-FFS 5*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -mtriple=arm64-apple-ios9.0 -S %s | FileCheck --check-prefix=CHECK-FFS %s 6*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -mtriple=arm64-apple-tvos9.0 -S %s | FileCheck --check-prefix=CHECK-FFS %s 7*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -mtriple=thumbv7k-apple-watchos2.0 -S %s | FileCheck --check-prefix=CHECK-FFS %s 8*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -mtriple=x86_64-apple-macosx10.11 -S %s | FileCheck --check-prefix=CHECK-FFS %s 9*9880d681SAndroid Build Coastguard Worker; RUN: opt -instcombine -mtriple=x86_64-freebsd-gnu -S %s | FileCheck --check-prefix=CHECK-FFS %s 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdeclare i32 @ffs(i32) 12*9880d681SAndroid Build Coastguard Workerdeclare i32 @ffsl(i32) 13*9880d681SAndroid Build Coastguard Workerdeclare i32 @ffsll(i64) 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; Check ffs(0) -> 0. 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify1() { 18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify1( 19*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffs(i32 0) 20*9880d681SAndroid Build Coastguard Worker ret i32 %ret 21*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 0 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify2() { 25*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify2( 26*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsl(i32 0) 27*9880d681SAndroid Build Coastguard Worker ret i32 %ret 28*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 0 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify3() { 32*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify3( 33*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 0) 34*9880d681SAndroid Build Coastguard Worker ret i32 %ret 35*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 0 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Check ffs(c) -> cttz(c) + 1, where 'c' is a constant. 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify4() { 41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify4( 42*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffs(i32 1) 43*9880d681SAndroid Build Coastguard Worker ret i32 %ret 44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 1 45*9880d681SAndroid Build Coastguard Worker} 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify5() { 48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify5( 49*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffs(i32 2048) 50*9880d681SAndroid Build Coastguard Worker ret i32 %ret 51*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 12 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify6() { 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify6( 56*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffs(i32 65536) 57*9880d681SAndroid Build Coastguard Worker ret i32 %ret 58*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 17 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify7() { 62*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify7( 63*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsl(i32 65536) 64*9880d681SAndroid Build Coastguard Worker ret i32 %ret 65*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 17 66*9880d681SAndroid Build Coastguard Worker} 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify8() { 69*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify8( 70*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 1024) 71*9880d681SAndroid Build Coastguard Worker ret i32 %ret 72*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 11 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify9() { 76*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify9( 77*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 65536) 78*9880d681SAndroid Build Coastguard Worker ret i32 %ret 79*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 17 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify10() { 83*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify10( 84*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 17179869184) 85*9880d681SAndroid Build Coastguard Worker ret i32 %ret 86*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 35 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify11() { 90*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify11( 91*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 281474976710656) 92*9880d681SAndroid Build Coastguard Worker ret i32 %ret 93*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 49 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify12() { 97*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify12( 98*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 1152921504606846976) 99*9880d681SAndroid Build Coastguard Worker ret i32 %ret 100*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 61 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Check ffs(x) -> x != 0 ? (i32)llvm.cttz(x) + 1 : 0. 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify13(i32 %x) { 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify13( 107*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffs(i32 %x) 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 true) 109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1 110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0 111*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0 112*9880d681SAndroid Build Coastguard Worker ret i32 %ret 113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[RET]] 114*9880d681SAndroid Build Coastguard Worker} 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify14(i32 %x) { 117*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify14( 118*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsl(i32 %x) 119*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 true) 120*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1 121*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0 122*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0 123*9880d681SAndroid Build Coastguard Worker ret i32 %ret 124*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 [[RET]] 125*9880d681SAndroid Build Coastguard Worker} 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify15(i64 %x) { 128*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-LABEL: @test_simplify15( 129*9880d681SAndroid Build Coastguard Worker %ret = call i32 @ffsll(i64 %x) 130*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[CTTZ:%[a-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %x, i1 true) 131*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i64 [[CTTZ]], 1 132*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[TRUNC:%[a-z0-9]+]] = trunc i64 [[INC]] to i32 133*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i64 %x, 0 134*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[TRUNC]], i32 0 135*9880d681SAndroid Build Coastguard Worker ret i32 %ret 136*9880d681SAndroid Build Coastguard Worker; CHECK-FFS-NEXT: ret i32 [[RET]] 137*9880d681SAndroid Build Coastguard Worker} 138