1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use.i3(i1) 5declare void @use.i5(i5) 6declare void @use.i32(i5) 7 8define i1 @or_xor_xor_normal_variant1(i1 %a, i1 %b) { 9; CHECK-LABEL: @or_xor_xor_normal_variant1( 10; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A:%.*]], [[B:%.*]] 11; CHECK-NEXT: ret i1 [[OR]] 12; 13 %and = and i1 %a, %b 14 %xor1 = xor i1 %and, %a 15 %xor2 = xor i1 %and, %b 16 %or = or i1 %xor1, %xor2 17 ret i1 %or 18} 19 20define i8 @or_xor_xor_normal_variant2(i8 %a, i8 %b) { 21; CHECK-LABEL: @or_xor_xor_normal_variant2( 22; CHECK-NEXT: [[OR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 23; CHECK-NEXT: ret i8 [[OR]] 24; 25 %and = and i8 %a, %b 26 %xor1 = xor i8 %and, %b 27 %xor2 = xor i8 %a, %and 28 %or = or i8 %xor1, %xor2 29 ret i8 %or 30} 31 32define i16 @or_xor_xor_normal_variant3(i16 %a, i16 %b) { 33; CHECK-LABEL: @or_xor_xor_normal_variant3( 34; CHECK-NEXT: [[OR:%.*]] = xor i16 [[B:%.*]], [[A:%.*]] 35; CHECK-NEXT: ret i16 [[OR]] 36; 37 %and = and i16 %b, %a 38 %xor1 = xor i16 %b, %and 39 %xor2 = xor i16 %a, %and 40 %or = or i16 %xor1, %xor2 41 ret i16 %or 42} 43 44define i64 @or_xor_xor_normal_variant4(i64 %a, i64 %b) { 45; CHECK-LABEL: @or_xor_xor_normal_variant4( 46; CHECK-NEXT: [[OR:%.*]] = xor i64 [[B:%.*]], [[A:%.*]] 47; CHECK-NEXT: ret i64 [[OR]] 48; 49 %and = and i64 %b, %a 50 %xor1 = xor i64 %and, %b 51 %xor2 = xor i64 %and, %a 52 %or = or i64 %xor1, %xor2 53 ret i64 %or 54} 55 56define i32 @or_xor_xor_normal_binops(i32 %aa, i32 %bb, i32 %cc) { 57; CHECK-LABEL: @or_xor_xor_normal_binops( 58; CHECK-NEXT: [[OR:%.*]] = xor i32 [[BB:%.*]], [[AA:%.*]] 59; CHECK-NEXT: ret i32 [[OR]] 60; 61 %a = xor i32 %aa, %cc 62 %b = xor i32 %bb, %cc 63 64 %and = and i32 %b, %a 65 %xor1 = xor i32 %b, %and 66 %xor2 = xor i32 %a, %and 67 %or = or i32 %xor1, %xor2 68 ret i32 %or 69} 70 71define <3 x i1> @or_xor_xor_normal_vector(<3 x i1> %a, <3 x i1> %b) { 72; CHECK-LABEL: @or_xor_xor_normal_vector( 73; CHECK-NEXT: [[OR:%.*]] = xor <3 x i1> [[A:%.*]], [[B:%.*]] 74; CHECK-NEXT: ret <3 x i1> [[OR]] 75; 76 %and = and <3 x i1> %a, %b 77 %xor1 = xor <3 x i1> %and, %b 78 %xor2 = xor <3 x i1> %and, %a 79 %or = or <3 x i1> %xor1, %xor2 80 ret <3 x i1> %or 81} 82 83define i3 @or_xor_xor_normal_multiple_uses_and(i3 %a, i3 %b) { 84; CHECK-LABEL: @or_xor_xor_normal_multiple_uses_and( 85; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[B:%.*]] 86; CHECK-NEXT: call void @use.i3(i3 [[AND]]) 87; CHECK-NEXT: [[OR:%.*]] = xor i3 [[A]], [[B]] 88; CHECK-NEXT: ret i3 [[OR]] 89; 90 %and = and i3 %a, %b 91 call void @use.i3(i3 %and) 92 %xor1 = xor i3 %b, %and 93 %xor2 = xor i3 %a, %and 94 %or = or i3 %xor1, %xor2 95 ret i3 %or 96} 97 98define i32 @or_xor_xor_negative_multiple_uses_xor1(i32 %a, i32 %b) { 99; CHECK-LABEL: @or_xor_xor_negative_multiple_uses_xor1( 100; CHECK-NEXT: [[AND1:%.*]] = xor i32 [[A:%.*]], -1 101; CHECK-NEXT: [[XOR1:%.*]] = and i32 [[B:%.*]], [[AND1]] 102; CHECK-NEXT: call void @use.i32(i32 [[XOR1]]) 103; CHECK-NEXT: [[OR:%.*]] = xor i32 [[A]], [[B]] 104; CHECK-NEXT: ret i32 [[OR]] 105; 106 %and = and i32 %a, %b 107 %xor1 = xor i32 %and, %b 108 call void @use.i32(i32 %xor1) 109 %xor2 = xor i32 %and, %a 110 %or = or i32 %xor1, %xor2 111 ret i32 %or 112} 113 114define i5 @or_xor_xor_negative_multiple_uses_xor2(i5 %a, i5 %b) { 115; CHECK-LABEL: @or_xor_xor_negative_multiple_uses_xor2( 116; CHECK-NEXT: [[A1:%.*]] = xor i5 [[B:%.*]], -1 117; CHECK-NEXT: [[XOR2:%.*]] = and i5 [[A:%.*]], [[A1]] 118; CHECK-NEXT: call void @use.i5(i5 [[XOR2]]) 119; CHECK-NEXT: [[OR:%.*]] = xor i5 [[A]], [[B]] 120; CHECK-NEXT: ret i5 [[OR]] 121; 122 %and = and i5 %a, %b 123 %xor1 = xor i5 %and, %b 124 %xor2 = xor i5 %and, %a 125 call void @use.i5(i5 %xor2) 126 %or = or i5 %xor1, %xor2 127 ret i5 %or 128} 129