brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 8998be5 Raw
233 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Transform5;   z = ~(x & y)6; into:7;   z = ~(~x | ~y)8; iff both x and y are free to invert.9 10declare void @use1(i1)11 12; Most basic positive test13define i1 @t0(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {14; CHECK-LABEL: @t0(15; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]16; CHECK-NEXT:    [[I2:%.*]] = icmp ne i32 [[V2:%.*]], [[V3:%.*]]17; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]18; CHECK-NEXT:    ret i1 [[I3_NOT]]19;20  %i1 = icmp eq i32 %v0, %v121  %i2 = icmp eq i32 %v2, %v322  %i3 = select i1 %i2, i1 %i1, i1 false23  %i4 = xor i1 %i3, -124  ret i1 %i425}26 27; All operands must be invertible28define i1 @n1(i1 %i1, i32 %v2, i32 %v3) {29; CHECK-LABEL: @n1(30; CHECK-NEXT:    [[I2:%.*]] = icmp eq i32 [[V2:%.*]], [[V3:%.*]]31; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1:%.*]], i1 false32; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[I3]], true33; CHECK-NEXT:    ret i1 [[I4]]34;35  %i2 = icmp eq i32 %v2, %v336  %i3 = select i1 %i2, i1 %i1, i1 false37  %i4 = xor i1 %i3, -138  ret i1 %i439}40define i1 @n2(i32 %v0, i32 %v1, i1 %i2) {41; CHECK-LABEL: @n2(42; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]43; CHECK-NEXT:    [[NOT_I2:%.*]] = xor i1 [[I2:%.*]], true44; CHECK-NEXT:    [[I3:%.*]] = select i1 [[NOT_I2]], i1 true, i1 [[I1]]45; CHECK-NEXT:    ret i1 [[I3]]46;47  %i1 = icmp eq i32 %v0, %v148  %i3 = select i1 %i2, i1 %i1, i1 false49  %i4 = xor i1 %i3, -150  ret i1 %i451}52define i1 @n3(i1 %i1, i1 %i2) {53; CHECK-LABEL: @n3(54; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2:%.*]], i1 [[I1:%.*]], i1 false55; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[I3]], true56; CHECK-NEXT:    ret i1 [[I4]]57;58  %i3 = select i1 %i2, i1 %i1, i1 false59  %i4 = xor i1 %i3, -160  ret i1 %i461}62 63; All other uses of operands must be invertible64define i1 @n4(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {65; CHECK-LABEL: @n4(66; CHECK-NEXT:    [[I1:%.*]] = icmp eq i32 [[V0:%.*]], [[V1:%.*]]67; CHECK-NEXT:    [[I2:%.*]] = icmp eq i32 [[V2:%.*]], [[V3:%.*]]68; CHECK-NEXT:    call void @use1(i1 [[I1]])69; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1]], i1 false70; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[I3]], true71; CHECK-NEXT:    ret i1 [[I4]]72;73  %i1 = icmp eq i32 %v0, %v174  %i2 = icmp eq i32 %v2, %v375  call void @use1(i1 %i1)76  %i3 = select i1 %i2, i1 %i1, i1 false77  %i4 = xor i1 %i3, -178  ret i1 %i479}80define i1 @n5(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {81; CHECK-LABEL: @n5(82; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]83; CHECK-NEXT:    [[I2:%.*]] = icmp eq i32 [[V2:%.*]], [[V3:%.*]]84; CHECK-NEXT:    call void @use1(i1 [[I2]])85; CHECK-NEXT:    [[NOT_I2:%.*]] = xor i1 [[I2]], true86; CHECK-NEXT:    [[I3:%.*]] = select i1 [[NOT_I2]], i1 true, i1 [[I1]]87; CHECK-NEXT:    ret i1 [[I3]]88;89  %i1 = icmp eq i32 %v0, %v190  %i2 = icmp eq i32 %v2, %v391  call void @use1(i1 %i2)92  %i3 = select i1 %i2, i1 %i1, i1 false93  %i4 = xor i1 %i3, -194  ret i1 %i495}96define i1 @n6(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {97; CHECK-LABEL: @n6(98; CHECK-NEXT:    [[I1:%.*]] = icmp eq i32 [[V0:%.*]], [[V1:%.*]]99; CHECK-NEXT:    [[I2:%.*]] = icmp eq i32 [[V2:%.*]], [[V3:%.*]]100; CHECK-NEXT:    call void @use1(i1 [[I1]])101; CHECK-NEXT:    call void @use1(i1 [[I2]])102; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1]], i1 false103; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[I3]], true104; CHECK-NEXT:    ret i1 [[I4]]105;106  %i1 = icmp eq i32 %v0, %v1107  %i2 = icmp eq i32 %v2, %v3108  call void @use1(i1 %i1)109  call void @use1(i1 %i2)110  %i3 = select i1 %i2, i1 %i1, i1 false111  %i4 = xor i1 %i3, -1112  ret i1 %i4113}114 115; Hands have invertible uses116define i1 @t7(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {117; CHECK-LABEL: @t7(118; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]119; CHECK-NEXT:    call void @use1(i1 [[I1]])120; CHECK-NEXT:    [[I2:%.*]] = icmp ne i32 [[V2:%.*]], [[V3:%.*]]121; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]122; CHECK-NEXT:    ret i1 [[I3_NOT]]123;124  %i1 = icmp eq i32 %v0, %v1125  %i1.not = xor i1 %i1, -1126  call void @use1(i1 %i1.not)127  %i2 = icmp eq i32 %v2, %v3128  %i3 = select i1 %i2, i1 %i1, i1 false129  %i4 = xor i1 %i3, -1130  ret i1 %i4131}132define i1 @t8(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {133; CHECK-LABEL: @t8(134; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]135; CHECK-NEXT:    [[I2:%.*]] = icmp ne i32 [[V2:%.*]], [[V3:%.*]]136; CHECK-NEXT:    call void @use1(i1 [[I2]])137; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]138; CHECK-NEXT:    ret i1 [[I3_NOT]]139;140  %i1 = icmp eq i32 %v0, %v1141  %i2 = icmp eq i32 %v2, %v3142  %i2.not = xor i1 %i2, -1143  call void @use1(i1 %i2.not)144  %i3 = select i1 %i2, i1 %i1, i1 false145  %i4 = xor i1 %i3, -1146  ret i1 %i4147}148define i1 @t9(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {149; CHECK-LABEL: @t9(150; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]151; CHECK-NEXT:    call void @use1(i1 [[I1]])152; CHECK-NEXT:    [[I2:%.*]] = icmp ne i32 [[V2:%.*]], [[V3:%.*]]153; CHECK-NEXT:    call void @use1(i1 [[I2]])154; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]155; CHECK-NEXT:    ret i1 [[I3_NOT]]156;157  %i1 = icmp eq i32 %v0, %v1158  %i1.not = xor i1 %i1, -1159  call void @use1(i1 %i1.not)160  %i2 = icmp eq i32 %v2, %v3161  %i2.not = xor i1 %i2, -1162  call void @use1(i1 %i2.not)163  %i3 = select i1 %i2, i1 %i1, i1 false164  %i4 = xor i1 %i3, -1165  ret i1 %i4166}167 168; Select can have other uses169 170; Not all uses can be adapted171define i1 @n10(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {172; CHECK-LABEL: @n10(173; CHECK-NEXT:    [[I1:%.*]] = icmp eq i32 [[V0:%.*]], [[V1:%.*]]174; CHECK-NEXT:    [[I2:%.*]] = icmp eq i32 [[V2:%.*]], [[V3:%.*]]175; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1]], i1 false176; CHECK-NEXT:    call void @use1(i1 [[I3]])177; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[I3]], true178; CHECK-NEXT:    ret i1 [[I4]]179;180  %i1 = icmp eq i32 %v0, %v1181  %i2 = icmp eq i32 %v2, %v3182  %i3 = select i1 %i2, i1 %i1, i1 false183  call void @use1(i1 %i3)184  %i4 = xor i1 %i3, -1185  ret i1 %i4186}187 188; All other uses can be adapted.189define i1 @t11(i32 %v0, i32 %v1, i32 %v2, i32 %v3, i1 %v4, i1 %v5) {190; CHECK-LABEL: @t11(191; CHECK-NEXT:    [[I1:%.*]] = icmp ne i32 [[V0:%.*]], [[V1:%.*]]192; CHECK-NEXT:    [[I2:%.*]] = icmp ne i32 [[V2:%.*]], [[V3:%.*]]193; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]194; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I3_NOT]], i1 [[V5:%.*]], i1 [[V4:%.*]]195; CHECK-NEXT:    call void @use1(i1 [[I5]])196; CHECK-NEXT:    ret i1 [[I3_NOT]]197;198  %i1 = icmp eq i32 %v0, %v1199  %i2 = icmp eq i32 %v2, %v3200  %i3 = select i1 %i2, i1 %i1, i1 false201  %i4 = xor i1 %i3, -1202  %i5 = select i1 %i3, i1 %v4, i1 %v5203  call void @use1(i1 %i5)204  ret i1 %i4205}206 207; This would miscompile by not handling the unsimplified select correctly.208 209define i1 @PR59704(i1 %c, i1 %b, i64 %arg) {210; CHECK-LABEL: @PR59704(211; CHECK-NEXT:  entry:212; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]213; CHECK:       if:214; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[ARG:%.*]], 0215; CHECK-NEXT:    br label [[JOIN]]216; CHECK:       join:217; CHECK-NEXT:    [[PHI:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[CMP_NOT]], [[IF]] ]218; CHECK-NEXT:    ret i1 [[PHI]]219;220entry:221  br i1 %c, label %if, label %join222 223if:224  %cmp = icmp ne i64 %arg, 0225  %and = select i1 %cmp, i1 %cmp, i1 false226  br label %join227 228join:229  %phi = phi i1 [ false, %entry ], [ %and, %if ]230  %not = xor i1 %phi, true231  ret i1 %not232}233