1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; Non-canonical mask 5 6define <4 x i32> @and(<4 x i32> %x, <4 x i32> %y) { 7; CHECK-LABEL: @and( 8; CHECK-NEXT: [[R:%.*]] = and <4 x i32> [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: ret <4 x i32> [[R]] 10; 11 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3> 12 %sel2 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 2, i32 7> 13 %r = and <4 x i32> %sel1, %sel2 14 ret <4 x i32> %r 15} 16 17define <vscale x 4 x i32> @vscaleand(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) { 18; CHECK-LABEL: @vscaleand( 19; CHECK-NEXT: [[TMP1:%.*]] = and <vscale x 4 x i32> [[X:%.*]], [[Y:%.*]] 20; CHECK-NEXT: [[R:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer 21; CHECK-NEXT: ret <vscale x 4 x i32> [[R]] 22; 23 %sel1 = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer 24 %sel2 = shufflevector <vscale x 4 x i32> %y, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer 25 %r = and <vscale x 4 x i32> %sel1, %sel2 26 ret <vscale x 4 x i32> %r 27} 28 29define <4 x i32> @or(<4 x i32> %x, <4 x i32> %y) { 30; CHECK-LABEL: @or( 31; CHECK-NEXT: [[R:%.*]] = or <4 x i32> [[X:%.*]], [[Y:%.*]] 32; CHECK-NEXT: ret <4 x i32> [[R]] 33; 34 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3> 35 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3> 36 %r = or <4 x i32> %sel1, %sel2 37 ret <4 x i32> %r 38} 39 40; Non-canonical masks 41 42define <4 x i32> @xor(<4 x i32> %x, <4 x i32> %y) { 43; CHECK-LABEL: @xor( 44; CHECK-NEXT: [[R:%.*]] = xor <4 x i32> [[Y:%.*]], [[X:%.*]] 45; CHECK-NEXT: ret <4 x i32> [[R]] 46; 47 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 48 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 49 %r = xor <4 x i32> %sel1, %sel2 50 ret <4 x i32> %r 51} 52 53; Flags 54 55define <4 x i32> @add(<4 x i32> %x, <4 x i32> %y) { 56; CHECK-LABEL: @add( 57; CHECK-NEXT: [[R:%.*]] = add nsw <4 x i32> [[X:%.*]], [[Y:%.*]] 58; CHECK-NEXT: ret <4 x i32> [[R]] 59; 60 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 61 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 62 %r = add nsw <4 x i32> %sel1, %sel2 63 ret <4 x i32> %r 64} 65 66; Negative test - wrong operand 67 68define <4 x i32> @add_wrong_op(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) { 69; CHECK-LABEL: @add_wrong_op( 70; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 71; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[Z:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 72; CHECK-NEXT: [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]] 73; CHECK-NEXT: ret <4 x i32> [[R]] 74; 75 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 76 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %z, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 77 %r = add nsw <4 x i32> %sel1, %sel2 78 ret <4 x i32> %r 79} 80 81; Negative test - wrong mask (but we could handle this...) 82 83define <4 x i32> @add_non_select_mask(<4 x i32> %x, <4 x i32> %y) { 84; CHECK-LABEL: @add_non_select_mask( 85; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 1, i32 5, i32 2, i32 7> 86; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 1, i32 5, i32 2, i32 7> 87; CHECK-NEXT: [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]] 88; CHECK-NEXT: ret <4 x i32> [[R]] 89; 90 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 5, i32 2, i32 7> 91 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 1, i32 5, i32 2, i32 7> 92 %r = add nsw <4 x i32> %sel1, %sel2 93 ret <4 x i32> %r 94} 95 96; Negative test - wrong mask (but we could handle this...) 97 98define <4 x i32> @add_masks_with_undefs(<4 x i32> %x, <4 x i32> %y) { 99; CHECK-LABEL: @add_masks_with_undefs( 100; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 poison, i32 5, i32 2, i32 7> 101; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 poison, i32 5, i32 2, i32 7> 102; CHECK-NEXT: [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]] 103; CHECK-NEXT: ret <4 x i32> [[R]] 104; 105 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 undef, i32 5, i32 2, i32 7> 106 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 undef, i32 5, i32 2, i32 7> 107 %r = add nsw <4 x i32> %sel1, %sel2 108 ret <4 x i32> %r 109} 110 111; Non-commutative opcode 112 113define <4 x i32> @sub(<4 x i32> %x, <4 x i32> %y) { 114; CHECK-LABEL: @sub( 115; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 116; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 117; CHECK-NEXT: [[R:%.*]] = sub <4 x i32> [[SEL1]], [[SEL2]] 118; CHECK-NEXT: ret <4 x i32> [[R]] 119; 120 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 121 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 122 %r = sub <4 x i32> %sel1, %sel2 123 ret <4 x i32> %r 124} 125 126define <4 x i32> @mul(<4 x i32> %x, <4 x i32> %y) { 127; CHECK-LABEL: @mul( 128; CHECK-NEXT: [[R:%.*]] = mul nuw <4 x i32> [[X:%.*]], [[Y:%.*]] 129; CHECK-NEXT: ret <4 x i32> [[R]] 130; 131 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 132 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 133 %r = mul nuw <4 x i32> %sel1, %sel2 134 ret <4 x i32> %r 135} 136 137define <4 x i32> @sdiv(<4 x i32> %x, <4 x i32> %y) { 138; CHECK-LABEL: @sdiv( 139; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 140; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 141; CHECK-NEXT: [[R:%.*]] = sdiv <4 x i32> [[SEL1]], [[SEL2]] 142; CHECK-NEXT: ret <4 x i32> [[R]] 143; 144 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 145 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 146 %r = sdiv <4 x i32> %sel1, %sel2 147 ret <4 x i32> %r 148} 149 150define <4 x i32> @udiv(<4 x i32> %x, <4 x i32> %y) { 151; CHECK-LABEL: @udiv( 152; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 153; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 154; CHECK-NEXT: [[R:%.*]] = udiv <4 x i32> [[SEL1]], [[SEL2]] 155; CHECK-NEXT: ret <4 x i32> [[R]] 156; 157 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 158 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 159 %r = udiv <4 x i32> %sel1, %sel2 160 ret <4 x i32> %r 161} 162 163define <4 x i32> @srem(<4 x i32> %x, <4 x i32> %y) { 164; CHECK-LABEL: @srem( 165; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 166; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 167; CHECK-NEXT: [[R:%.*]] = srem <4 x i32> [[SEL1]], [[SEL2]] 168; CHECK-NEXT: ret <4 x i32> [[R]] 169; 170 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 171 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 172 %r = srem <4 x i32> %sel1, %sel2 173 ret <4 x i32> %r 174} 175 176define <4 x i32> @urem(<4 x i32> %x, <4 x i32> %y) { 177; CHECK-LABEL: @urem( 178; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 179; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3> 180; CHECK-NEXT: [[R:%.*]] = urem <4 x i32> [[SEL1]], [[SEL2]] 181; CHECK-NEXT: ret <4 x i32> [[R]] 182; 183 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 184 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 185 %r = urem <4 x i32> %sel1, %sel2 186 ret <4 x i32> %r 187} 188 189define <4 x i32> @shl(<4 x i32> %x, <4 x i32> %y) { 190; CHECK-LABEL: @shl( 191; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 192; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> 193; CHECK-NEXT: [[R:%.*]] = shl nsw <4 x i32> [[SEL1]], [[SEL2]] 194; CHECK-NEXT: ret <4 x i32> [[R]] 195; 196 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 197 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7> 198 %r = shl nsw <4 x i32> %sel1, %sel2 199 ret <4 x i32> %r 200} 201 202define <4 x i32> @lshr(<4 x i32> %x, <4 x i32> %y) { 203; CHECK-LABEL: @lshr( 204; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3> 205; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 5, i32 6, i32 3> 206; CHECK-NEXT: [[R:%.*]] = lshr exact <4 x i32> [[SEL1]], [[SEL2]] 207; CHECK-NEXT: ret <4 x i32> [[R]] 208; 209 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3> 210 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3> 211 %r = lshr exact <4 x i32> %sel1, %sel2 212 ret <4 x i32> %r 213} 214 215define <4 x i32> @ashr(<4 x i32> %x, <4 x i32> %y) { 216; CHECK-LABEL: @ashr( 217; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 218; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 219; CHECK-NEXT: [[R:%.*]] = ashr <4 x i32> [[SEL1]], [[SEL2]] 220; CHECK-NEXT: ret <4 x i32> [[R]] 221; 222 %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 223 %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 224 %r = ashr <4 x i32> %sel1, %sel2 225 ret <4 x i32> %r 226} 227 228define <4 x float> @fadd(<4 x float> %x, <4 x float> %y) { 229; CHECK-LABEL: @fadd( 230; CHECK-NEXT: [[R:%.*]] = fadd <4 x float> [[Y:%.*]], [[X:%.*]] 231; CHECK-NEXT: ret <4 x float> [[R]] 232; 233 %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 234 %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 235 %r = fadd <4 x float> %sel1, %sel2 236 ret <4 x float> %r 237} 238 239define <4 x float> @fsub(<4 x float> %x, <4 x float> %y) { 240; CHECK-LABEL: @fsub( 241; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 242; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 243; CHECK-NEXT: [[R:%.*]] = fsub fast <4 x float> [[SEL1]], [[SEL2]] 244; CHECK-NEXT: ret <4 x float> [[R]] 245; 246 %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 247 %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 248 %r = fsub fast <4 x float> %sel1, %sel2 249 ret <4 x float> %r 250} 251 252define <4 x double> @fmul(<4 x double> %x, <4 x double> %y) { 253; CHECK-LABEL: @fmul( 254; CHECK-NEXT: [[R:%.*]] = fmul nnan <4 x double> [[Y:%.*]], [[X:%.*]] 255; CHECK-NEXT: ret <4 x double> [[R]] 256; 257 %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 258 %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 259 %r = fmul nnan <4 x double> %sel1, %sel2 260 ret <4 x double> %r 261} 262 263define <4 x double> @fdiv(<4 x double> %x, <4 x double> %y) { 264; CHECK-LABEL: @fdiv( 265; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 266; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 267; CHECK-NEXT: [[R:%.*]] = fdiv nnan arcp <4 x double> [[SEL1]], [[SEL2]] 268; CHECK-NEXT: ret <4 x double> [[R]] 269; 270 %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 271 %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 272 %r = fdiv arcp nnan <4 x double> %sel1, %sel2 273 ret <4 x double> %r 274} 275 276define <4 x double> @frem(<4 x double> %x, <4 x double> %y) { 277; CHECK-LABEL: @frem( 278; CHECK-NEXT: [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 279; CHECK-NEXT: [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 280; CHECK-NEXT: [[R:%.*]] = frem <4 x double> [[SEL1]], [[SEL2]] 281; CHECK-NEXT: ret <4 x double> [[R]] 282; 283 %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 284 %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 285 %r = frem <4 x double> %sel1, %sel2 286 ret <4 x double> %r 287} 288