1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 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, 0 10 %s = sub i32 0, %x 11 %d = select i1 %c, i32 %s, i32 %x 12 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 13 ret i32 %r 14} 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, zeroinitializer 22 %s = sub <2 x i64> zeroinitializer, %x 23 %d = select <2 x i1> %c, <2 x i64> %s, <2 x i64> %x 24 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d) 25 ret <2 x i64> %r 26} 27 28define i32 @cttz_abs2(i32 %x) { 29; CHECK-LABEL: @cttz_abs2( 30; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], 0 31; 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, 0 36 call void @use_cond(i1 %c) 37 %s = sub i32 0, %x 38 %d = select i1 %c, i32 %x, i32 %s 39 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 40 ret i32 %r 41} 42 43define i32 @cttz_abs3(i32 %x) { 44; CHECK-LABEL: @cttz_abs3( 45; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -1 46; 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, -1 51 call void @use_cond(i1 %c) 52 %s = sub i32 0, %x 53 %d = select i1 %c, i32 %x, i32 %s 54 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 55 ret i32 %r 56} 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, 1 64 %s = sub i32 0, %x 65 %d = select i1 %c, i32 %s, i32 %x 66 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 67 ret i32 %r 68} 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, 0 76 %s = sub i32 0, %x 77 %d = select i1 %c, i32 %x, i32 %s 78 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 false) 79 ret i32 %r 80} 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, zeroinitializer 88 %s = sub <2 x i64> zeroinitializer, %x 89 %d = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %s 90 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d) 91 ret <2 x i64> %r 92} 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, 0 100 %s = sub i64 0, %x 101 %d = select i1 %c, i64 %s, i64 %x 102 %r = tail call i64 @llvm.cttz.i64(i64 %d) 103 ret i64 %r 104} 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, 1 114 %s = sub i32 0, %x 115 %d = select i1 %c, i32 %s, i32 %x 116 call void @use_abs(i32 %d) 117 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 118 ret i32 %r 119} 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, 1 130 %s = sub i32 0, %x 131 %d = select i1 %c, i32 %x, i32 %s 132 call void @use_abs(i32 %d) 133 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 134 ret i32 %r 135} 136 137; Negative tests 138 139define i32 @no_cttz_abs(i32 %x) { 140; CHECK-LABEL: @no_cttz_abs( 141; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 2 142; 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, 2 148 %s = sub i32 0, %x 149 %d = select i1 %c, i32 %s, i32 %x 150 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 151 ret i32 %r 152} 153 154define i32 @no_cttz_abs2(i32 %x) { 155; CHECK-LABEL: @no_cttz_abs2( 156; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 0 157; 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, 0 163 %s = sub i32 1, %x 164 %d = select i1 %c, i32 %s, i32 %x 165 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 166 ret i32 %r 167} 168 169define i32 @no_cttz_abs3(i32 %x) { 170; CHECK-LABEL: @no_cttz_abs3( 171; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2 172; 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, -2 179 call void @use_cond(i1 %c) 180 %s = sub i32 0, %x 181 %d = select i1 %c, i32 %x, i32 %s 182 %r = tail call i32 @llvm.cttz.i32(i32 %d, i1 true) 183 ret i32 %r 184} 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>, %x 196 %d = select <2 x i1> %c, <2 x i64> %s, <2 x i64> %x 197 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d) 198 ret <2 x i64> %r 199} 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>, %x 211 %d = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %s 212 %r = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %d) 213 ret <2 x i64> %r 214} 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 %r 224} 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, %a 233 %r = call i32 @llvm.cttz.i32(i32 %n, i1 false) 234 ret i32 %r 235} 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