221 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i32 @test_or_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {5; CHECK-LABEL: define i32 @test_or_fshl(6; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {7; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], [[C]]8; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[B]], [[D]]9; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])10; CHECK-NEXT: ret i32 [[RET]]11;12 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)13 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)14 %ret = or i32 %val1, %val215 ret i32 %ret16}17define i32 @test_and_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {18; CHECK-LABEL: define i32 @test_and_fshl(19; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {20; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], [[C]]21; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B]], [[D]]22; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])23; CHECK-NEXT: ret i32 [[RET]]24;25 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)26 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)27 %ret = and i32 %val1, %val228 ret i32 %ret29}30define i32 @test_xor_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {31; CHECK-LABEL: define i32 @test_xor_fshl(32; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {33; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[C]]34; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[B]], [[D]]35; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])36; CHECK-NEXT: ret i32 [[RET]]37;38 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)39 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)40 %ret = xor i32 %val1, %val241 ret i32 %ret42}43define i32 @test_or_fshr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {44; CHECK-LABEL: define i32 @test_or_fshr(45; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {46; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], [[C]]47; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[B]], [[D]]48; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])49; CHECK-NEXT: ret i32 [[RET]]50;51 %val1 = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %sh)52 %val2 = call i32 @llvm.fshr.i32(i32 %c, i32 %d, i32 %sh)53 %ret = or i32 %val1, %val254 ret i32 %ret55}56define i32 @test_or_fshl_cascade(i32 %a, i32 %b, i32 %c) {57; CHECK-LABEL: define i32 @test_or_fshl_cascade(58; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {59; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], [[B]]60; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[A]], [[B]]61; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], [[C]]62; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[C]]63; CHECK-NEXT: [[OR2:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP3]], i32 [[TMP4]], i32 24)64; CHECK-NEXT: ret i32 [[OR2]]65;66 %fshl1 = call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 24)67 %fshl2 = call i32 @llvm.fshl.i32(i32 %b, i32 %b, i32 24)68 %fshl3 = call i32 @llvm.fshl.i32(i32 %c, i32 %c, i32 24)69 %or1 = or i32 %fshl1, %fshl270 %or2 = or i32 %or1, %fshl371 ret i32 %or272}73define i32 @test_or_bitreverse(i32 %a, i32 %b) {74; CHECK-LABEL: define i32 @test_or_bitreverse(75; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {76; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], [[B]]77; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[TMP1]])78; CHECK-NEXT: ret i32 [[RET]]79;80 %val1 = call i32 @llvm.bitreverse.i32(i32 %a)81 %val2 = call i32 @llvm.bitreverse.i32(i32 %b)82 %ret = or i32 %val1, %val283 ret i32 %ret84}85define i32 @test_or_bitreverse_constant(i32 %a, i32 %b) {86; CHECK-LABEL: define i32 @test_or_bitreverse_constant(87; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {88; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], 25589; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[TMP1]])90; CHECK-NEXT: ret i32 [[RET]]91;92 %val1 = call i32 @llvm.bitreverse.i32(i32 %a)93 %ret = or i32 %val1, 427819008094 ret i32 %ret95}96define i32 @test_or_bswap(i32 %a, i32 %b) {97; CHECK-LABEL: define i32 @test_or_bswap(98; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {99; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], [[B]]100; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])101; CHECK-NEXT: ret i32 [[RET]]102;103 %val1 = call i32 @llvm.bswap.i32(i32 %a)104 %val2 = call i32 @llvm.bswap.i32(i32 %b)105 %ret = or i32 %val1, %val2106 ret i32 %ret107}108define i32 @test_or_bswap_constant(i32 %a, i32 %b) {109; CHECK-LABEL: define i32 @test_or_bswap_constant(110; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {111; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A]], 255112; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])113; CHECK-NEXT: ret i32 [[RET]]114;115 %val1 = call i32 @llvm.bswap.i32(i32 %a)116 %ret = or i32 %val1, 4278190080117 ret i32 %ret118}119 120; Negative tests121 122define i32 @test_or_fshl_fshr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {123; CHECK-LABEL: define i32 @test_or_fshl_fshr(124; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {125; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])126; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.fshr.i32(i32 [[C]], i32 [[D]], i32 [[SH]])127; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]128; CHECK-NEXT: ret i32 [[RET]]129;130 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)131 %val2 = call i32 @llvm.fshr.i32(i32 %c, i32 %d, i32 %sh)132 %ret = or i32 %val1, %val2133 ret i32 %ret134}135define i32 @test_or_bitreverse_bswap(i32 %a, i32 %b) {136; CHECK-LABEL: define i32 @test_or_bitreverse_bswap(137; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {138; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])139; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.bswap.i32(i32 [[B]])140; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]141; CHECK-NEXT: ret i32 [[RET]]142;143 %val1 = call i32 @llvm.bitreverse.i32(i32 %a)144 %val2 = call i32 @llvm.bswap.i32(i32 %b)145 %ret = or i32 %val1, %val2146 ret i32 %ret147}148define i32 @test_or_fshl_mismatched_shamt(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh1, i32 %sh2) {149; CHECK-LABEL: define i32 @test_or_fshl_mismatched_shamt(150; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH1:%.*]], i32 [[SH2:%.*]]) {151; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH1]])152; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH2]])153; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]154; CHECK-NEXT: ret i32 [[RET]]155;156 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh1)157 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh2)158 %ret = or i32 %val1, %val2159 ret i32 %ret160}161define i32 @test_add_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {162; CHECK-LABEL: define i32 @test_add_fshl(163; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {164; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])165; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH]])166; CHECK-NEXT: [[RET:%.*]] = add i32 [[VAL1]], [[VAL2]]167; CHECK-NEXT: ret i32 [[RET]]168;169 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)170 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)171 %ret = add i32 %val1, %val2172 ret i32 %ret173}174define i32 @test_or_fshl_multiuse(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {175; CHECK-LABEL: define i32 @test_or_fshl_multiuse(176; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {177; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])178; CHECK-NEXT: call void @use(i32 [[VAL1]])179; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH]])180; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]181; CHECK-NEXT: ret i32 [[RET]]182;183 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)184 call void @use(i32 %val1)185 %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)186 %ret = or i32 %val1, %val2187 ret i32 %ret188}189define i32 @test_or_bitreverse_multiuse(i32 %a, i32 %b) {190; CHECK-LABEL: define i32 @test_or_bitreverse_multiuse(191; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {192; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])193; CHECK-NEXT: call void @use(i32 [[VAL1]])194; CHECK-NEXT: [[VAL2:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[B]])195; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]196; CHECK-NEXT: ret i32 [[RET]]197;198 %val1 = call i32 @llvm.bitreverse.i32(i32 %a)199 call void @use(i32 %val1)200 %val2 = call i32 @llvm.bitreverse.i32(i32 %b)201 %ret = or i32 %val1, %val2202 ret i32 %ret203}204define i32 @test_or_fshl_constant(i32 %a, i32 %b, i32 %sh) {205; CHECK-LABEL: define i32 @test_or_fshl_constant(206; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[SH:%.*]]) {207; CHECK-NEXT: [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])208; CHECK-NEXT: [[RET:%.*]] = or i32 [[VAL1]], -16777216209; CHECK-NEXT: ret i32 [[RET]]210;211 %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)212 %ret = or i32 %val1, 4278190080213 ret i32 %ret214}215 216declare void @use(i32)217declare i32 @llvm.fshl.i32(i32, i32, i32)218declare i32 @llvm.fshr.i32(i32, i32, i32)219declare i32 @llvm.bitreverse.i32(i32)220declare i32 @llvm.bswap.i32(i32)221