243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4define i32 @cttz_abs(i32 %x) {5; CHECK-LABEL: @cttz_abs(6; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)7; CHECK-NEXT: ret i32 [[R]]8;9 %c = icmp slt i32 %x, 010 %s = sub i32 0, %x11 %d = select i1 %c, i32 %s, i32 %x12 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)13 ret i32 %r14}15 16define <2 x i64> @cttz_abs_vec(<2 x i64> %x) {17; CHECK-LABEL: @cttz_abs_vec(18; CHECK-NEXT: [[R:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false)19; CHECK-NEXT: ret <2 x i64> [[R]]20;21 %c = icmp slt <2 x i64> %x, zeroinitializer22 %s = sub <2 x i64> zeroinitializer, %x23 %d = select <2 x i1> %c, <2 x i64> %s, <2 x i64> %x24 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d)25 ret <2 x i64> %r26}27 28define i32 @cttz_abs2(i32 %x) {29; CHECK-LABEL: @cttz_abs2(30; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], 031; CHECK-NEXT: call void @use_cond(i1 [[C]])32; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 true)33; CHECK-NEXT: ret i32 [[R]]34;35 %c = icmp sgt i32 %x, 036 call void @use_cond(i1 %c)37 %s = sub i32 0, %x38 %d = select i1 %c, i32 %x, i32 %s39 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)40 ret i32 %r41}42 43define i32 @cttz_abs3(i32 %x) {44; CHECK-LABEL: @cttz_abs3(45; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -146; CHECK-NEXT: call void @use_cond(i1 [[C]])47; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 true)48; CHECK-NEXT: ret i32 [[R]]49;50 %c = icmp sgt i32 %x, -151 call void @use_cond(i1 %c)52 %s = sub i32 0, %x53 %d = select i1 %c, i32 %x, i32 %s54 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)55 ret i32 %r56}57 58define i32 @cttz_abs4(i32 %x) {59; CHECK-LABEL: @cttz_abs4(60; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)61; CHECK-NEXT: ret i32 [[R]]62;63 %c = icmp slt i32 %x, 164 %s = sub i32 0, %x65 %d = select i1 %c, i32 %s, i32 %x66 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)67 ret i32 %r68}69 70define i32 @cttz_nabs(i32 %x) {71; CHECK-LABEL: @cttz_nabs(72; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)73; CHECK-NEXT: ret i32 [[R]]74;75 %c = icmp slt i32 %x, 076 %s = sub i32 0, %x77 %d = select i1 %c, i32 %x, i32 %s78 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 false)79 ret i32 %r80}81 82define <2 x i64> @cttz_nabs_vec(<2 x i64> %x) {83; CHECK-LABEL: @cttz_nabs_vec(84; CHECK-NEXT: [[R:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false)85; CHECK-NEXT: ret <2 x i64> [[R]]86;87 %c = icmp slt <2 x i64> %x, zeroinitializer88 %s = sub <2 x i64> zeroinitializer, %x89 %d = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %s90 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d)91 ret <2 x i64> %r92}93 94define i64 @cttz_abs_64(i64 %x) {95; CHECK-LABEL: @cttz_abs_64(96; CHECK-NEXT: [[R:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)97; CHECK-NEXT: ret i64 [[R]]98;99 %c = icmp slt i64 %x, 0100 %s = sub i64 0, %x101 %d = select i1 %c, i64 %s, i64 %x102 %r = tail call i64 @llvm.cttz.i64(i64 %d)103 ret i64 %r104}105 106define i32 @cttz_abs_multiuse(i32 %x) {107; CHECK-LABEL: @cttz_abs_multiuse(108; CHECK-NEXT: [[D:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)109; CHECK-NEXT: call void @use_abs(i32 [[D]])110; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 true)111; CHECK-NEXT: ret i32 [[R]]112;113 %c = icmp slt i32 %x, 1114 %s = sub i32 0, %x115 %d = select i1 %c, i32 %s, i32 %x116 call void @use_abs(i32 %d)117 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)118 ret i32 %r119}120 121define i32 @cttz_nabs_multiuse(i32 %x) {122; CHECK-LABEL: @cttz_nabs_multiuse(123; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)124; CHECK-NEXT: [[D:%.*]] = sub i32 0, [[TMP1]]125; CHECK-NEXT: call void @use_abs(i32 [[D]])126; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 true)127; CHECK-NEXT: ret i32 [[R]]128;129 %c = icmp slt i32 %x, 1130 %s = sub i32 0, %x131 %d = select i1 %c, i32 %x, i32 %s132 call void @use_abs(i32 %d)133 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)134 ret i32 %r135}136 137; Negative tests138 139define i32 @no_cttz_abs(i32 %x) {140; CHECK-LABEL: @no_cttz_abs(141; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 2142; CHECK-NEXT: [[S:%.*]] = sub i32 0, [[X]]143; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[S]], i32 [[X]]144; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[D]], i1 true)145; CHECK-NEXT: ret i32 [[R]]146;147 %c = icmp slt i32 %x, 2148 %s = sub i32 0, %x149 %d = select i1 %c, i32 %s, i32 %x150 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)151 ret i32 %r152}153 154define i32 @no_cttz_abs2(i32 %x) {155; CHECK-LABEL: @no_cttz_abs2(156; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 0157; CHECK-NEXT: [[S:%.*]] = sub i32 1, [[X]]158; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[S]], i32 [[X]]159; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[D]], i1 true)160; CHECK-NEXT: ret i32 [[R]]161;162 %c = icmp slt i32 %x, 0163 %s = sub i32 1, %x164 %d = select i1 %c, i32 %s, i32 %x165 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)166 ret i32 %r167}168 169define i32 @no_cttz_abs3(i32 %x) {170; CHECK-LABEL: @no_cttz_abs3(171; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2172; CHECK-NEXT: call void @use_cond(i1 [[C]])173; CHECK-NEXT: [[S:%.*]] = sub i32 0, [[X]]174; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[X]], i32 [[S]]175; CHECK-NEXT: [[R:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[D]], i1 true)176; CHECK-NEXT: ret i32 [[R]]177;178 %c = icmp sgt i32 %x, -2179 call void @use_cond(i1 %c)180 %s = sub i32 0, %x181 %d = select i1 %c, i32 %x, i32 %s182 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true)183 ret i32 %r184}185 186define <2 x i64> @no_cttz_abs_vec(<2 x i64> %x) {187; CHECK-LABEL: @no_cttz_abs_vec(188; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i64> [[X:%.*]], <i64 2, i64 1>189; CHECK-NEXT: [[S:%.*]] = sub <2 x i64> <i64 1, i64 0>, [[X]]190; CHECK-NEXT: [[D:%.*]] = select <2 x i1> [[C]], <2 x i64> [[S]], <2 x i64> [[X]]191; CHECK-NEXT: [[R:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[D]], i1 false)192; CHECK-NEXT: ret <2 x i64> [[R]]193;194 %c = icmp slt <2 x i64> %x, <i64 2, i64 1>195 %s = sub <2 x i64> <i64 1, i64 0>, %x196 %d = select <2 x i1> %c, <2 x i64> %s, <2 x i64> %x197 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d)198 ret <2 x i64> %r199}200 201define <2 x i64> @no_cttz_nabs_vec(<2 x i64> %x) {202; CHECK-LABEL: @no_cttz_nabs_vec(203; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i64> [[X:%.*]], <i64 2, i64 1>204; CHECK-NEXT: [[S:%.*]] = sub <2 x i64> <i64 1, i64 0>, [[X]]205; CHECK-NEXT: [[D:%.*]] = select <2 x i1> [[C]], <2 x i64> [[X]], <2 x i64> [[S]]206; CHECK-NEXT: [[R:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[D]], i1 false)207; CHECK-NEXT: ret <2 x i64> [[R]]208;209 %c = icmp slt <2 x i64> %x, <i64 2, i64 1>210 %s = sub <2 x i64> <i64 1, i64 0>, %x211 %d = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %s212 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d)213 ret <2 x i64> %r214}215 216define i32 @cttz_abs_intrin(i32 %x) {217; CHECK-LABEL: @cttz_abs_intrin(218; CHECK-NEXT: [[R:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)219; CHECK-NEXT: ret i32 [[R]]220;221 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)222 %r = call i32 @llvm.cttz.i32(i32 %a, i1 false)223 ret i32 %r224}225 226define i32 @cttz_nabs_intrin(i32 %x) {227; CHECK-LABEL: @cttz_nabs_intrin(228; CHECK-NEXT: [[R:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)229; CHECK-NEXT: ret i32 [[R]]230;231 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)232 %n = sub i32 0, %a233 %r = call i32 @llvm.cttz.i32(i32 %n, i1 false)234 ret i32 %r235}236 237declare void @use_cond(i1)238declare void @use_abs(i32)239declare i32 @llvm.cttz.i32(i32, i1)240declare i64 @llvm.cttz.i64(i64)241declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>)242declare i32 @llvm.abs.i32(i32, i1)243