194 lines · plain
1; Test that the ffs* library call simplifier works correctly.2;3; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC4; RUN: opt < %s -passes=instcombine -mtriple i386-pc-linux -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET5; RUN: opt < %s -passes=instcombine -mtriple=arm64-apple-ios9.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET6; RUN: opt < %s -passes=instcombine -mtriple=arm64-apple-tvos9.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET7; RUN: opt < %s -passes=instcombine -mtriple=thumbv7k-apple-watchos2.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET8; RUN: opt < %s -passes=instcombine -mtriple=x86_64-apple-macosx10.11 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET9; RUN: opt < %s -passes=instcombine -mtriple=x86_64-freebsd-gnu -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET10 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 020;21 %ret = call i32 @ffs(i32 0)22 ret i32 %ret23}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 032;33 %ret = call i32 @ffsl(i32 0)34 ret i32 %ret35}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 044;45 %ret = call i32 @ffsll(i64 0)46 ret i32 %ret47}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 154;55 %ret = call i32 @ffs(i32 1)56 ret i32 %ret57}58 59define i32 @test_simplify5() {60; ALL-LABEL: @test_simplify5(61; ALL-NEXT: ret i32 1262;63 %ret = call i32 @ffs(i32 2048)64 ret i32 %ret65}66 67define i32 @test_simplify6() {68; ALL-LABEL: @test_simplify6(69; ALL-NEXT: ret i32 1770;71 %ret = call i32 @ffs(i32 65536)72 ret i32 %ret73}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 1782;83 %ret = call i32 @ffsl(i32 65536)84 ret i32 %ret85}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 1194;95 %ret = call i32 @ffsll(i64 1024)96 ret i32 %ret97}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 17106;107 %ret = call i32 @ffsll(i64 65536)108 ret i32 %ret109}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 35118;119 %ret = call i32 @ffsll(i64 17179869184)120 ret i32 %ret121}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 49130;131 %ret = call i32 @ffsll(i64 281474976710656)132 ret i32 %ret133}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 61142;143 %ret = call i32 @ffsll(i64 1152921504606846976)144 ret i32 %ret145}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 range(i32 0, 33) i32 @llvm.cttz.i32(i32 %x, i1 true)152; ALL-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1153; ALL-NEXT: [[TMP2:%.*]] = icmp eq i32 %x, 0154; 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 %ret159}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 range(i32 0, 33) i32 @llvm.cttz.i32(i32 %x, i1 true)168; TARGET-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1169; TARGET-NEXT: [[TMP2:%.*]] = icmp eq i32 %x, 0170; 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 %ret175}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 range(i64 0, 65) i64 @llvm.cttz.i64(i64 %x, i1 true)184; TARGET-NEXT: [[TMP1:%.*]] = trunc nuw nsw i64 [[CTTZ]] to i32185; TARGET-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1186; TARGET-NEXT: [[TMP3:%.*]] = icmp eq i64 %x, 0187; 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 %ret192}193 194