116 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare void @use(i32)5 6define i32 @sub_to_xor(i32 %x, i32 %y) {7; CHECK-LABEL: @sub_to_xor(8; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]9; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]10; CHECK-NEXT: ret i32 [[SUB]]11;12 %or = or i32 %x, %y13 %and = and i32 %x, %y14 %sub = sub i32 %and, %or15 ret i32 %sub16}17 18define i32 @sub_to_xor_extra_use_sub(i32 %x, i32 %y) {19; CHECK-LABEL: @sub_to_xor_extra_use_sub(20; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]21; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]22; CHECK-NEXT: call void @use(i32 [[SUB]])23; CHECK-NEXT: ret i32 [[SUB]]24;25 %or = or i32 %x, %y26 %and = and i32 %x, %y27 %sub = sub i32 %and, %or28 call void @use(i32 %sub)29 ret i32 %sub30}31 32define i32 @sub_to_xor_extra_use_and(i32 %x, i32 %y) {33; CHECK-LABEL: @sub_to_xor_extra_use_and(34; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]35; CHECK-NEXT: call void @use(i32 [[AND]])36; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]]37; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]38; CHECK-NEXT: ret i32 [[SUB]]39;40 %or = or i32 %x, %y41 %and = and i32 %x, %y42 call void @use(i32 %and)43 %sub = sub i32 %and, %or44 ret i32 %sub45}46 47define i32 @sub_to_xor_extra_use_or(i32 %x, i32 %y) {48; CHECK-LABEL: @sub_to_xor_extra_use_or(49; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]50; CHECK-NEXT: call void @use(i32 [[OR]])51; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]]52; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]53; CHECK-NEXT: ret i32 [[SUB]]54;55 %or = or i32 %x, %y56 call void @use(i32 %or)57 %and = and i32 %x, %y58 %sub = sub i32 %and, %or59 ret i32 %sub60}61 62define i32 @sub_to_xor_or_commuted(i32 %x, i32 %y) {63; CHECK-LABEL: @sub_to_xor_or_commuted(64; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]65; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]66; CHECK-NEXT: ret i32 [[SUB]]67;68 %or = or i32 %y, %x69 %and = and i32 %x, %y70 %sub = sub i32 %and, %or71 ret i32 %sub72}73 74define i32 @sub_to_xor_and_commuted(i32 %x, i32 %y) {75; CHECK-LABEL: @sub_to_xor_and_commuted(76; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]77; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[TMP1]]78; CHECK-NEXT: ret i32 [[SUB]]79;80 %or = or i32 %x, %y81 %and = and i32 %y, %x82 %sub = sub i32 %and, %or83 ret i32 %sub84}85 86define <2 x i32> @sub_to_xor_vec(<2 x i32> %x, <2 x i32> %y) {87; CHECK-LABEL: @sub_to_xor_vec(88; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[Y:%.*]], [[X:%.*]]89; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[TMP1]]90; CHECK-NEXT: ret <2 x i32> [[SUB]]91;92 %or = or <2 x i32> %x, %y93 %and = and <2 x i32> %y, %x94 %sub = sub <2 x i32> %and, %or95 ret <2 x i32> %sub96}97 98; Negative tests99 100define i32 @sub_to_xor_extra_use_and_or(i32 %x, i32 %y) {101; CHECK-LABEL: @sub_to_xor_extra_use_and_or(102; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]103; CHECK-NEXT: call void @use(i32 [[OR]])104; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]105; CHECK-NEXT: call void @use(i32 [[AND]])106; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[AND]], [[OR]]107; CHECK-NEXT: ret i32 [[SUB]]108;109 %or = or i32 %x, %y110 call void @use(i32 %or)111 %and = and i32 %x, %y112 call void @use(i32 %and)113 %sub = sub i32 %and, %or114 ret i32 %sub115}116