1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i64 @add_select_zext(i1 %c) { 5; CHECK-LABEL: define i64 @add_select_zext 6; CHECK-SAME: (i1 [[C:%.*]]) { 7; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i64 65, i64 1 8; CHECK-NEXT: ret i64 [[ADD]] 9; 10 %sel = select i1 %c, i64 64, i64 1 11 %ext = zext i1 %c to i64 12 %add = add i64 %sel, %ext 13 ret i64 %add 14} 15 16define i64 @add_select_sext(i1 %c) { 17; CHECK-LABEL: define i64 @add_select_sext 18; CHECK-SAME: (i1 [[C:%.*]]) { 19; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i64 63, i64 1 20; CHECK-NEXT: ret i64 [[ADD]] 21; 22 %sel = select i1 %c, i64 64, i64 1 23 %ext = sext i1 %c to i64 24 %add = add i64 %sel, %ext 25 ret i64 %add 26} 27 28define i64 @add_select_not_zext(i1 %c) { 29; CHECK-LABEL: define i64 @add_select_not_zext 30; CHECK-SAME: (i1 [[C:%.*]]) { 31; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i64 64, i64 2 32; CHECK-NEXT: ret i64 [[ADD]] 33; 34 %sel = select i1 %c, i64 64, i64 1 35 %not.c = xor i1 %c, true 36 %ext = zext i1 %not.c to i64 37 %add = add i64 %sel, %ext 38 ret i64 %add 39} 40 41define i64 @add_select_not_sext(i1 %c) { 42; CHECK-LABEL: define i64 @add_select_not_sext 43; CHECK-SAME: (i1 [[C:%.*]]) { 44; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i64 64, i64 0 45; CHECK-NEXT: ret i64 [[ADD]] 46; 47 %sel = select i1 %c, i64 64, i64 1 48 %not.c = xor i1 %c, true 49 %ext = sext i1 %not.c to i64 50 %add = add i64 %sel, %ext 51 ret i64 %add 52} 53 54define i64 @sub_select_sext(i1 %c, i64 %arg) { 55; CHECK-LABEL: define i64 @sub_select_sext 56; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { 57; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i64 65, i64 [[ARG]] 58; CHECK-NEXT: ret i64 [[SUB]] 59; 60 %sel = select i1 %c, i64 64, i64 %arg 61 %ext = sext i1 %c to i64 62 %sub = sub i64 %sel, %ext 63 ret i64 %sub 64} 65 66define i64 @sub_select_not_zext(i1 %c, i64 %arg) { 67; CHECK-LABEL: define i64 @sub_select_not_zext 68; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { 69; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i64 [[ARG]], i64 63 70; CHECK-NEXT: ret i64 [[SUB]] 71; 72 %sel = select i1 %c, i64 %arg, i64 64 73 %not.c = xor i1 %c, true 74 %ext = zext i1 %not.c to i64 75 %sub = sub i64 %sel, %ext 76 ret i64 %sub 77} 78 79define i64 @sub_select_not_sext(i1 %c, i64 %arg) { 80; CHECK-LABEL: define i64 @sub_select_not_sext 81; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { 82; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i64 [[ARG]], i64 65 83; CHECK-NEXT: ret i64 [[SUB]] 84; 85 %sel = select i1 %c, i64 %arg, i64 64 86 %not.c = xor i1 %c, true 87 %ext = sext i1 %not.c to i64 88 %sub = sub i64 %sel, %ext 89 ret i64 %sub 90} 91 92define i64 @mul_select_zext(i1 %c, i64 %arg) { 93; CHECK-LABEL: define i64 @mul_select_zext 94; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG:%.*]]) { 95; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C]], i64 [[ARG]], i64 0 96; CHECK-NEXT: ret i64 [[MUL]] 97; 98 %sel = select i1 %c, i64 %arg, i64 1 99 %ext = zext i1 %c to i64 100 %mul = mul i64 %sel, %ext 101 ret i64 %mul 102} 103 104define i64 @mul_select_sext(i1 %c) { 105; CHECK-LABEL: define i64 @mul_select_sext 106; CHECK-SAME: (i1 [[C:%.*]]) { 107; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C]], i64 -64, i64 0 108; CHECK-NEXT: ret i64 [[MUL]] 109; 110 %sel = select i1 %c, i64 64, i64 1 111 %ext = sext i1 %c to i64 112 %mul = mul i64 %sel, %ext 113 ret i64 %mul 114} 115 116define i64 @select_zext_different_condition(i1 %c, i1 %d) { 117; CHECK-LABEL: define i64 @select_zext_different_condition 118; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]]) { 119; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 64, i64 1 120; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[D]] to i64 121; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SEL]], [[EXT]] 122; CHECK-NEXT: ret i64 [[ADD]] 123; 124 %sel = select i1 %c, i64 64, i64 1 125 %ext = zext i1 %d to i64 126 %add = add i64 %sel, %ext 127 ret i64 %add 128} 129 130define <2 x i64> @vector_test(i1 %c) { 131; CHECK-LABEL: define <2 x i64> @vector_test 132; CHECK-SAME: (i1 [[C:%.*]]) { 133; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], <2 x i64> splat (i64 64), <2 x i64> splat (i64 1) 134; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[C]] to i64 135; CHECK-NEXT: [[VEC0:%.*]] = insertelement <2 x i64> poison, i64 [[EXT]], i64 0 136; CHECK-NEXT: [[VEC1:%.*]] = shufflevector <2 x i64> [[VEC0]], <2 x i64> poison, <2 x i32> zeroinitializer 137; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i64> [[SEL]], [[VEC1]] 138; CHECK-NEXT: ret <2 x i64> [[ADD]] 139; 140 %sel = select i1 %c, <2 x i64> <i64 64, i64 64>, <2 x i64> <i64 1, i64 1> 141 %ext = zext i1 %c to i64 142 %vec0 = insertelement <2 x i64> undef, i64 %ext, i32 0 143 %vec1 = insertelement <2 x i64> %vec0, i64 %ext, i32 1 144 %add = add <2 x i64> %sel, %vec1 145 ret <2 x i64> %add 146} 147 148define i64 @multiuse_add(i1 %c) { 149; CHECK-LABEL: define i64 @multiuse_add 150; CHECK-SAME: (i1 [[C:%.*]]) { 151; CHECK-NEXT: [[ADD2:%.*]] = select i1 [[C]], i64 66, i64 2 152; CHECK-NEXT: ret i64 [[ADD2]] 153; 154 %sel = select i1 %c, i64 64, i64 1 155 %ext = zext i1 %c to i64 156 %add = add i64 %sel, %ext 157 %add2 = add i64 %add, 1 158 ret i64 %add2 159} 160 161define i64 @multiuse_select(i1 %c) { 162; CHECK-LABEL: define i64 @multiuse_select 163; CHECK-SAME: (i1 [[C:%.*]]) { 164; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C]], i64 4032, i64 0 165; CHECK-NEXT: ret i64 [[MUL]] 166; 167 %sel = select i1 %c, i64 64, i64 0 168 %ext = zext i1 %c to i64 169 %add = sub i64 %sel, %ext 170 %mul = mul i64 %sel, %add 171 ret i64 %mul 172} 173 174define i64 @select_non_const_sides(i1 %c, i64 %arg1, i64 %arg2) { 175; CHECK-LABEL: define i64 @select_non_const_sides 176; CHECK-SAME: (i1 [[C:%.*]], i64 [[ARG1:%.*]], i64 [[ARG2:%.*]]) { 177; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ARG1]], -1 178; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i64 [[TMP1]], i64 [[ARG2]] 179; CHECK-NEXT: ret i64 [[SUB]] 180; 181 %ext = zext i1 %c to i64 182 %sel = select i1 %c, i64 %arg1, i64 %arg2 183 %sub = sub i64 %sel, %ext 184 ret i64 %sub 185} 186 187define i6 @sub_select_sext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) { 188; CHECK-LABEL: define i6 @sub_select_sext_op_swapped_non_const_args 189; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) { 190; CHECK-NEXT: [[TMP1:%.*]] = xor i6 [[ARGT]], -1 191; CHECK-NEXT: [[TMP2:%.*]] = sub i6 0, [[ARGF]] 192; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i6 [[TMP1]], i6 [[TMP2]] 193; CHECK-NEXT: ret i6 [[SUB]] 194; 195 %sel = select i1 %c, i6 %argT, i6 %argF 196 %ext = sext i1 %c to i6 197 %sub = sub i6 %ext, %sel 198 ret i6 %sub 199} 200 201define i6 @sub_select_zext_op_swapped_non_const_args(i1 %c, i6 %argT, i6 %argF) { 202; CHECK-LABEL: define i6 @sub_select_zext_op_swapped_non_const_args 203; CHECK-SAME: (i1 [[C:%.*]], i6 [[ARGT:%.*]], i6 [[ARGF:%.*]]) { 204; CHECK-NEXT: [[TMP1:%.*]] = sub i6 1, [[ARGT]] 205; CHECK-NEXT: [[TMP2:%.*]] = sub i6 0, [[ARGF]] 206; CHECK-NEXT: [[SUB:%.*]] = select i1 [[C]], i6 [[TMP1]], i6 [[TMP2]] 207; CHECK-NEXT: ret i6 [[SUB]] 208; 209 %sel = select i1 %c, i6 %argT, i6 %argF 210 %ext = zext i1 %c to i6 211 %sub = sub i6 %ext, %sel 212 ret i6 %sub 213} 214 215define <2 x i8> @vectorized_add(<2 x i1> %c, <2 x i8> %arg) { 216; CHECK-LABEL: define <2 x i8> @vectorized_add 217; CHECK-SAME: (<2 x i1> [[C:%.*]], <2 x i8> [[ARG:%.*]]) { 218; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[ARG]], splat (i8 1) 219; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[C]], <2 x i8> [[TMP1]], <2 x i8> splat (i8 1) 220; CHECK-NEXT: ret <2 x i8> [[ADD]] 221; 222 %zext = zext <2 x i1> %c to <2 x i8> 223 %sel = select <2 x i1> %c, <2 x i8> %arg, <2 x i8> <i8 1, i8 1> 224 %add = add <2 x i8> %sel, %zext 225 ret <2 x i8> %add 226} 227 228@b = external global [72 x i32] 229@c = external global i32 230 231define i64 @pr64669(i64 %a) { 232; CHECK-LABEL: define i64 @pr64669 233; CHECK-SAME: (i64 [[A:%.*]]) { 234; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @b, i64 100), @c 235; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[A]], 1 236; CHECK-NEXT: [[ADD:%.*]] = select i1 [[CMP_NOT]], i64 0, i64 [[TMP1]] 237; CHECK-NEXT: ret i64 [[ADD]] 238; 239 %cmp = icmp ne ptr getelementptr inbounds ([72 x i32], ptr @b, i64 0, i64 25), @c 240 %mul = select i1 %cmp, i64 %a, i64 0 241 %conv3 = zext i1 %cmp to i64 242 %add = add nsw i64 %mul, %conv3 243 ret i64 %add 244} 245