270 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Basic pattern5define i8 @t0(i8 %x, i1 %cond) {6; CHECK-LABEL: @t0(7; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]8; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND:%.*]], i8 [[X_NEG]], i8 [[X]]9; CHECK-NEXT: ret i8 [[XOR]]10;11 %cond.splat = sext i1 %cond to i812 %sub = add i8 %cond.splat, %x13 %xor = xor i8 %sub, %cond.splat14 ret i8 %xor15}16define <2 x i8> @t0_vec(<2 x i8> %x, <2 x i1> %cond) {17; CHECK-LABEL: @t0_vec(18; CHECK-NEXT: [[X_NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]19; CHECK-NEXT: [[XOR:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i8> [[X_NEG]], <2 x i8> [[X]]20; CHECK-NEXT: ret <2 x i8> [[XOR]]21;22 %cond.splat = sext <2 x i1> %cond to <2 x i8>23 %sub = add <2 x i8> %cond.splat, %x24 %xor = xor <2 x i8> %sub, %cond.splat25 ret <2 x i8> %xor26}27 28; Two different extensions are fine29define i8 @t1(i8 %x, i1 %cond) {30; CHECK-LABEL: @t1(31; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]32; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND:%.*]], i8 [[X_NEG]], i8 [[X]]33; CHECK-NEXT: ret i8 [[XOR]]34;35 %cond.splat0 = sext i1 %cond to i836 %cond.splat1 = sext i1 %cond to i837 %sub = add i8 %cond.splat0, %x38 %xor = xor i8 %sub, %cond.splat139 ret i8 %xor40}41 42; Two different extensions of different conditions are not fine43define i8 @t2(i8 %x, i1 %cond0, i1 %cond1) {44; CHECK-LABEL: @t2(45; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND0:%.*]] to i846; CHECK-NEXT: [[COND_SPLAT1:%.*]] = sext i1 [[COND1:%.*]] to i847; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT0]]48; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]49; CHECK-NEXT: ret i8 [[XOR]]50;51 %cond.splat0 = sext i1 %cond0 to i852 %cond.splat1 = sext i1 %cond1 to i853 %sub = add i8 %cond.splat0, %x54 %xor = xor i8 %sub, %cond.splat155 ret i8 %xor56}57 58; Condition must be boolean.59define i8 @t3(i8 %x, i2 %cond) {60; CHECK-LABEL: @t3(61; CHECK-NEXT: [[COND_SPLAT:%.*]] = sext i2 [[COND:%.*]] to i862; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT]]63; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]64; CHECK-NEXT: ret i8 [[XOR]]65;66 %cond.splat = sext i2 %cond to i867 %sub = add i8 %cond.splat, %x68 %xor = xor i8 %sub, %cond.splat69 ret i8 %xor70}71define <2 x i8> @t3_vec(<2 x i8> %x, <2 x i2> %cond) {72; CHECK-LABEL: @t3_vec(73; CHECK-NEXT: [[COND_SPLAT:%.*]] = sext <2 x i2> [[COND:%.*]] to <2 x i8>74; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X:%.*]], [[COND_SPLAT]]75; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[SUB]], [[COND_SPLAT]]76; CHECK-NEXT: ret <2 x i8> [[XOR]]77;78 %cond.splat = sext <2 x i2> %cond to <2 x i8>79 %sub = add <2 x i8> %cond.splat, %x80 %xor = xor <2 x i8> %sub, %cond.splat81 ret <2 x i8> %xor82}83 84; add is commutative85; xor is not commutative here because of complexity ordering86define i8 @xor.commuted(i1 %cond) {87; CHECK-LABEL: @xor.commuted(88; CHECK-NEXT: [[X:%.*]] = call i8 @gen.i8()89; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X]]90; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND:%.*]], i8 [[X_NEG]], i8 [[X]]91; CHECK-NEXT: ret i8 [[XOR]]92;93 %cond.splat = sext i1 %cond to i894 %x = call i8 @gen.i8()95 %sub = add i8 %x, %cond.splat96 %xor = xor i8 %sub, %cond.splat97 ret i8 %xor98}99 100; Extra use tests101define i8 @extrause01_v1(i8 %x, i1 %cond) {102; CHECK-LABEL: @extrause01_v1(103; CHECK-NEXT: [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8104; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT]])105; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]106; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]107; CHECK-NEXT: ret i8 [[XOR]]108;109 %cond.splat = sext i1 %cond to i8110 call void @use.i8(i8 %cond.splat)111 %sub = add i8 %cond.splat, %x112 %xor = xor i8 %sub, %cond.splat113 ret i8 %xor114}115define i8 @extrause10_v1(i8 %x, i1 %cond) {116; CHECK-LABEL: @extrause10_v1(117; CHECK-NEXT: [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8118; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT]]119; CHECK-NEXT: call void @use.i8(i8 [[SUB]])120; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]121; CHECK-NEXT: ret i8 [[XOR]]122;123 %cond.splat = sext i1 %cond to i8124 %sub = add i8 %cond.splat, %x125 call void @use.i8(i8 %sub)126 %xor = xor i8 %sub, %cond.splat127 ret i8 %xor128}129define i8 @extrause11_v1(i8 %x, i1 %cond) {130; CHECK-LABEL: @extrause11_v1(131; CHECK-NEXT: [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8132; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT]])133; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT]]134; CHECK-NEXT: call void @use.i8(i8 [[SUB]])135; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]136; CHECK-NEXT: ret i8 [[XOR]]137;138 %cond.splat = sext i1 %cond to i8139 call void @use.i8(i8 %cond.splat)140 %sub = add i8 %cond.splat, %x141 call void @use.i8(i8 %sub)142 %xor = xor i8 %sub, %cond.splat143 ret i8 %xor144}145 146; Extra use tests with two extensions147define i8 @extrause001_v2(i8 %x, i1 %cond) {148; CHECK-LABEL: @extrause001_v2(149; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8150; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT0]])151; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]152; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]153; CHECK-NEXT: ret i8 [[XOR]]154;155 %cond.splat0 = sext i1 %cond to i8156 call void @use.i8(i8 %cond.splat0)157 %cond.splat1 = sext i1 %cond to i8158 %sub = add i8 %cond.splat0, %x159 %xor = xor i8 %sub, %cond.splat1160 ret i8 %xor161}162define i8 @extrause010_v2(i8 %x, i1 %cond) {163; CHECK-LABEL: @extrause010_v2(164; CHECK-NEXT: [[COND_SPLAT1:%.*]] = sext i1 [[COND:%.*]] to i8165; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT1]])166; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]167; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]168; CHECK-NEXT: ret i8 [[XOR]]169;170 %cond.splat0 = sext i1 %cond to i8171 %cond.splat1 = sext i1 %cond to i8172 call void @use.i8(i8 %cond.splat1)173 %sub = add i8 %cond.splat0, %x174 %xor = xor i8 %sub, %cond.splat1175 ret i8 %xor176}177define i8 @extrause011_v2(i8 %x, i1 %cond) {178; CHECK-LABEL: @extrause011_v2(179; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8180; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT0]])181; CHECK-NEXT: [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8182; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT1]])183; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]184; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]185; CHECK-NEXT: ret i8 [[XOR]]186;187 %cond.splat0 = sext i1 %cond to i8188 call void @use.i8(i8 %cond.splat0)189 %cond.splat1 = sext i1 %cond to i8190 call void @use.i8(i8 %cond.splat1)191 %sub = add i8 %cond.splat0, %x192 %xor = xor i8 %sub, %cond.splat1193 ret i8 %xor194}195define i8 @extrause100_v2(i8 %x, i1 %cond) {196; CHECK-LABEL: @extrause100_v2(197; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8198; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT0]]199; CHECK-NEXT: call void @use.i8(i8 [[SUB]])200; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X]]201; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]202; CHECK-NEXT: ret i8 [[XOR]]203;204 %cond.splat0 = sext i1 %cond to i8205 %cond.splat1 = sext i1 %cond to i8206 %sub = add i8 %cond.splat0, %x207 call void @use.i8(i8 %sub)208 %xor = xor i8 %sub, %cond.splat1209 ret i8 %xor210}211define i8 @extrause101_v2(i8 %x, i1 %cond) {212; CHECK-LABEL: @extrause101_v2(213; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8214; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT0]])215; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT0]]216; CHECK-NEXT: call void @use.i8(i8 [[SUB]])217; CHECK-NEXT: [[X_NEG:%.*]] = sub i8 0, [[X]]218; CHECK-NEXT: [[XOR:%.*]] = select i1 [[COND]], i8 [[X_NEG]], i8 [[X]]219; CHECK-NEXT: ret i8 [[XOR]]220;221 %cond.splat0 = sext i1 %cond to i8222 call void @use.i8(i8 %cond.splat0)223 %cond.splat1 = sext i1 %cond to i8224 %sub = add i8 %cond.splat0, %x225 call void @use.i8(i8 %sub)226 %xor = xor i8 %sub, %cond.splat1227 ret i8 %xor228}229define i8 @extrause110_v2(i8 %x, i1 %cond) {230; CHECK-LABEL: @extrause110_v2(231; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8232; CHECK-NEXT: [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8233; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT1]])234; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT0]]235; CHECK-NEXT: call void @use.i8(i8 [[SUB]])236; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]237; CHECK-NEXT: ret i8 [[XOR]]238;239 %cond.splat0 = sext i1 %cond to i8240 %cond.splat1 = sext i1 %cond to i8241 call void @use.i8(i8 %cond.splat1)242 %sub = add i8 %cond.splat0, %x243 call void @use.i8(i8 %sub)244 %xor = xor i8 %sub, %cond.splat1245 ret i8 %xor246}247define i8 @extrause111_v2(i8 %x, i1 %cond) {248; CHECK-LABEL: @extrause111_v2(249; CHECK-NEXT: [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8250; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT0]])251; CHECK-NEXT: [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8252; CHECK-NEXT: call void @use.i8(i8 [[COND_SPLAT1]])253; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[COND_SPLAT0]]254; CHECK-NEXT: call void @use.i8(i8 [[SUB]])255; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]256; CHECK-NEXT: ret i8 [[XOR]]257;258 %cond.splat0 = sext i1 %cond to i8259 call void @use.i8(i8 %cond.splat0)260 %cond.splat1 = sext i1 %cond to i8261 call void @use.i8(i8 %cond.splat1)262 %sub = add i8 %cond.splat0, %x263 call void @use.i8(i8 %sub)264 %xor = xor i8 %sub, %cond.splat1265 ret i8 %xor266}267 268declare void @use.i8(i8)269declare i8 @gen.i8()270