1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4declare void @use8(i8) 5declare void @use1(i1) 6 7; Basic case - all good. 8define i8 @p0(i8 %x, i8 %v0, i8 %v1) { 9; CHECK-LABEL: @p0( 10; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 11; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 12; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0 13; CHECK-NEXT: ret i8 [[R]] 14; 15 %t0 = and i8 %x, 1 16 %t1 = icmp eq i8 %t0, 1 17 %r = select i1 %t1, i8 %v0, i8 %v1, !prof !0 18 ret i8 %r 19} 20define i8 @p1(i8 %x, i8 %v0, i8 %v1) { 21; CHECK-LABEL: @p1( 22; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 23; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 24; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] 25; CHECK-NEXT: ret i8 [[R]] 26; 27 %t0 = and i8 %x, 1 28 %t1 = icmp ne i8 %t0, 0 29 %r = select i1 %t1, i8 %v0, i8 %v1 30 ret i8 %r 31} 32 33; Can't invert all users of original condition 34define i8 @n2(i8 %x, i8 %v0, i8 %v1) { 35; CHECK-LABEL: @n2( 36; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 37; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0 38; CHECK-NEXT: call void @use1(i1 [[T1]]) 39; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] 40; CHECK-NEXT: ret i8 [[R]] 41; 42 %t0 = and i8 %x, 1 43 %t1 = icmp eq i8 %t0, 1 44 call void @use1(i1 %t1) ; condition has un-invertable use 45 %r = select i1 %t1, i8 %v0, i8 %v1 46 ret i8 %r 47} 48 49; Extra use can be adjusted. While there, test multi-bb case. 50define i8 @t3(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out, i1 %c) { 51; CHECK-LABEL: @t3( 52; CHECK-NEXT: bb0: 53; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 54; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 55; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 56; CHECK: bb1: 57; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] 58; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 59; CHECK-NEXT: br label [[BB2]] 60; CHECK: bb2: 61; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] 62; CHECK-NEXT: ret i8 [[R1]] 63; 64bb0: 65 %t0 = and i8 %x, 1 66 %t1 = icmp eq i8 %t0, 1 67 br i1 %c, label %bb1, label %bb2 68bb1: 69 %r0 = select i1 %t1, i8 %v0, i8 %v1 70 store i8 %r0, i8* %out 71 br label %bb2 72bb2: 73 %r1 = select i1 %t1, i8 %v2, i8 %v3 74 ret i8 %r1 75} 76define i8 @t4(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out) { 77; CHECK-LABEL: @t4( 78; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 79; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 80; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] 81; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 82; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] 83; CHECK-NEXT: ret i8 [[R1]] 84; 85 %t0 = and i8 %x, 1 86 %t1 = icmp ne i8 %t0, 0 87 %r0 = select i1 %t1, i8 %v0, i8 %v1 88 store i8 %r0, i8* %out 89 %r1 = select i1 %t1, i8 %v2, i8 %v3 90 ret i8 %r1 91} 92 93; Weird comparisons 94define i8 @n5(i8 %x, i8 %v0, i8 %v1) { 95; CHECK-LABEL: @n5( 96; CHECK-NEXT: ret i8 [[V1:%.*]] 97; 98 %t0 = and i8 %x, 1 99 %t1 = icmp eq i8 %t0, 2 ; checking some other bit 100 %r = select i1 %t1, i8 %v0, i8 %v1 101 ret i8 %r 102} 103define i8 @n6(i8 %x, i8 %v0, i8 %v1) { 104; CHECK-LABEL: @n6( 105; CHECK-NEXT: ret i8 [[V1:%.*]] 106; 107 %t0 = and i8 %x, 1 108 %t1 = icmp eq i8 %t0, 3 ; checking some other bit 109 %r = select i1 %t1, i8 %v0, i8 %v1 110 ret i8 %r 111} 112define i8 @n7(i8 %x, i8 %v0, i8 %v1) { 113; CHECK-LABEL: @n7( 114; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 115; CHECK-NEXT: [[T1_NOT_NOT:%.*]] = icmp eq i8 [[T0]], 0 116; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT_NOT]], i8 [[V0:%.*]], i8 [[V1:%.*]] 117; CHECK-NEXT: ret i8 [[R]] 118; 119 %t0 = and i8 %x, 1 120 %t1 = icmp ne i8 %t0, 1 ; not checking that it's zero 121 %r = select i1 %t1, i8 %v0, i8 %v1 122 ret i8 %r 123} 124 125; Potentially have more than a single bit set 126define i8 @n8(i8 %x, i8 %v0, i8 %v1) { 127; CHECK-LABEL: @n8( 128; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 3 129; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 1 130; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] 131; CHECK-NEXT: ret i8 [[R]] 132; 133 %t0 = and i8 %x, 3 ; Not a single bit 134 %t1 = icmp eq i8 %t0, 1 135 %r = select i1 %t1, i8 %v0, i8 %v1 136 ret i8 %r 137} 138 139!0 = !{!"branch_weights", i32 0, i32 100} 140 141; Ensure that the branch metadata is reversed to match the reversals above. 142; CHECK: !0 = {{.*}} i32 100, i32 0} 143