1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; Transform
; z = (~x) | y
; into:
; z = ~(x & (~y))
; iff y is free to invert and all uses of z can be freely updated.
declare void @use1(i1)
declare void @use8(i8)
; Most basic positive test
define i8 @t0(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
; CHECK-LABEL: @t0(
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I3_NOT:%.*]] = select i1 [[I0:%.*]], i1 [[I1]], i1 false
; CHECK-NEXT: [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: ret i8 [[I4]]
;
%i1 = icmp eq i8 %v0, %v1
%i2 = xor i1 %i0, -1
%i3 = select i1 %i2, i1 true, i1 %i1
%i4 = select i1 %i3, i8 %v2, i8 %v3
ret i8 %i4
}
define i8 @t0_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
; CHECK-LABEL: @t0_commutative(
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I3_NOT:%.*]] = select i1 [[I1]], i1 [[I0:%.*]], i1 false
; CHECK-NEXT: [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: ret i8 [[I4]]
;
%i1 = icmp eq i8 %v0, %v1
%i2 = xor i1 %i0, -1
%i3 = select i1 %i1, i1 true, i1 %i2
%i4 = select i1 %i3, i8 %v2, i8 %v3
ret i8 %i4
}
define i8 @t1(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
; CHECK-LABEL: @t1(
; CHECK-NEXT: [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
; CHECK-NEXT: call void @use1(i1 [[I0]])
; CHECK-NEXT: [[I3_NOT:%.*]] = select i1 [[I0]], i1 [[I1]], i1 false
; CHECK-NEXT: [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
; CHECK-NEXT: ret i8 [[I4]]
;
%i0 = icmp eq i8 %v0, %v1
%i1 = icmp eq i8 %v2, %v3
call void @use1(i1 %i0)
%i2 = xor i1 %i0, -1
%i3 = select i1 %i2, i1 true, i1 %i1
%i4 = select i1 %i3, i8 %v4, i8 %v5
ret i8 %i4
}
define i8 @t1_commutative(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
; CHECK-LABEL: @t1_commutative(
; CHECK-NEXT: [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
; CHECK-NEXT: call void @use1(i1 [[I0]])
; CHECK-NEXT: [[I3_NOT:%.*]] = select i1 [[I1]], i1 [[I0]], i1 false
; CHECK-NEXT: [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
; CHECK-NEXT: ret i8 [[I4]]
;
%i0 = icmp eq i8 %v0, %v1
%i1 = icmp eq i8 %v2, %v3
call void @use1(i1 %i0)
%i2 = xor i1 %i0, -1
%i3 = select i1 %i1, i1 true, i1 %i2
%i4 = select i1 %i3, i8 %v4, i8 %v5
ret i8 %i4
}
; All users of %i3 must be invertible
define i1 @n2(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
; CHECK-LABEL: @n2(
; CHECK-NEXT: [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I2:%.*]] = xor i1 [[I0:%.*]], true
; CHECK-NEXT: [[I3:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]
; CHECK-NEXT: ret i1 [[I3]]
;
%i1 = icmp eq i8 %v0, %v1
%i2 = xor i1 %i0, -1
%i3 = select i1 %i2, i1 true, i1 %i1
ret i1 %i3 ; can not be inverted
}
; %i1 must be invertible
define i8 @n3(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
; CHECK-LABEL: @n3(
; CHECK-NEXT: [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: call void @use1(i1 [[I1]])
; CHECK-NEXT: [[I2:%.*]] = xor i1 [[I0:%.*]], true
; CHECK-NEXT: [[I3:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]
; CHECK-NEXT: [[I4:%.*]] = select i1 [[I3]], i8 [[V2:%.*]], i8 [[V3:%.*]]
; CHECK-NEXT: ret i8 [[I4]]
;
%i1 = icmp eq i8 %v0, %v1 ; has extra uninvertible use
call void @use1(i1 %i1) ; bad extra use
%i2 = xor i1 %i0, -1
%i3 = select i1 %i2, i1 true, i1 %i1
%i4 = select i1 %i3, i8 %v2, i8 %v3
ret i8 %i4
}
; Extra uses are invertible
define i8 @t4(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
; CHECK-LABEL: @t4(
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: call void @use8(i8 [[I2]])
; CHECK-NEXT: [[I4_NOT:%.*]] = select i1 [[I0:%.*]], i1 [[I1]], i1 false
; CHECK-NEXT: [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
; CHECK-NEXT: ret i8 [[I5]]
;
%i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
%i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
call void @use8(i8 %i2)
%i3 = xor i1 %i0, -1
%i4 = select i1 %i3, i1 true, i1 %i1
%i5 = select i1 %i4, i8 %v4, i8 %v5
ret i8 %i5
}
define i8 @t4_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
; CHECK-LABEL: @t4_commutative(
; CHECK-NEXT: [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
; CHECK-NEXT: [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: call void @use8(i8 [[I2]])
; CHECK-NEXT: [[I4_NOT:%.*]] = select i1 [[I1]], i1 [[I0:%.*]], i1 false
; CHECK-NEXT: [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
; CHECK-NEXT: ret i8 [[I5]]
;
%i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
%i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
call void @use8(i8 %i2)
%i3 = xor i1 %i0, -1
%i4 = select i1 %i1, i1 true, i1 %i3
%i5 = select i1 %i4, i8 %v4, i8 %v5
ret i8 %i5
}
|