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