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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
declare void @use19(i19)
declare void @use12(i12)
declare void @use2(i2)
define i32 @add_or_sub_comb_i32_commuted1_nuw(i32 %x) {
; CHECK-LABEL: @add_or_sub_comb_i32_commuted1_nuw(
; CHECK-NEXT: ret i32 [[X:%.*]]
;
%sub = sub i32 0, %x
%or = or i32 %sub, %x
%add = add nuw i32 %or, %x
ret i32 %add
}
define i8 @add_or_sub_comb_i8_commuted2_nsw(i8 %p) {
; CHECK-LABEL: @add_or_sub_comb_i8_commuted2_nsw(
; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X]], -1
; CHECK-NEXT: [[ADD:%.*]] = and i8 [[TMP1]], [[X]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%x = mul i8 %p, %p ; thwart complexity-based canonicalization
%sub = sub i8 0, %x
%or = or i8 %sub, %x
%add = add nsw i8 %x, %or
ret i8 %add
}
define i128 @add_or_sub_comb_i128_commuted3_nuw_nsw(i128 %p) {
; CHECK-LABEL: @add_or_sub_comb_i128_commuted3_nuw_nsw(
; CHECK-NEXT: [[X:%.*]] = mul i128 [[P:%.*]], [[P]]
; CHECK-NEXT: ret i128 [[X]]
;
%x = mul i128 %p, %p ; thwart complexity-based canonicalization
%sub = sub i128 0, %x
%or = or i128 %x, %sub
%add = add nuw nsw i128 %or, %x
ret i128 %add
}
define i64 @add_or_sub_comb_i64_commuted4(i64 %p) {
; CHECK-LABEL: @add_or_sub_comb_i64_commuted4(
; CHECK-NEXT: [[X:%.*]] = mul i64 [[P:%.*]], [[P]]
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X]], -1
; CHECK-NEXT: [[ADD:%.*]] = and i64 [[TMP1]], [[X]]
; CHECK-NEXT: ret i64 [[ADD]]
;
%x = mul i64 %p, %p ; thwart complexity-based canonicalization
%sub = sub i64 0, %x
%or = or i64 %x, %sub
%add = add i64 %x, %or
ret i64 %add
}
define <3 x i32> @add_or_sub_comb_i32vec(<3 x i32> %p) {
; CHECK-LABEL: @add_or_sub_comb_i32vec(
; CHECK-NEXT: [[X:%.*]] = mul <3 x i32> [[P:%.*]], [[P]]
; CHECK-NEXT: [[TMP1:%.*]] = add <3 x i32> [[X]], <i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: [[ADD:%.*]] = and <3 x i32> [[TMP1]], [[X]]
; CHECK-NEXT: ret <3 x i32> [[ADD]]
;
%x = mul <3 x i32> %p, %p ; thwart complexity-based canonicalization
%sub = sub <3 x i32> <i32 0, i32 0, i32 0>, %x
%or = or <3 x i32> %sub, %x
%add = add <3 x i32> %or, %x
ret <3 x i32> %add
}
define <4 x i16> @add_or_sub_comb_i32vec_poison(<4 x i16> %p) {
; CHECK-LABEL: @add_or_sub_comb_i32vec_poison(
; CHECK-NEXT: [[X:%.*]] = mul <4 x i16> [[P:%.*]], [[P]]
; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i16> [[X]], <i16 -1, i16 -1, i16 -1, i16 -1>
; CHECK-NEXT: [[ADD:%.*]] = and <4 x i16> [[TMP1]], [[X]]
; CHECK-NEXT: ret <4 x i16> [[ADD]]
;
%x = mul <4 x i16> %p, %p ; thwart complexity-based canonicalization
%sub = sub <4 x i16> <i16 0, i16 poison, i16 poison, i16 0>, %x
%or = or <4 x i16> %sub, %x
%add = add <4 x i16> %or, %x
ret <4 x i16> %add
}
define i12 @add_or_sub_comb_i12_multiuse_only_sub(i12 %p) {
; CHECK-LABEL: @add_or_sub_comb_i12_multiuse_only_sub(
; CHECK-NEXT: [[X:%.*]] = mul i12 [[P:%.*]], [[P]]
; CHECK-NEXT: [[SUB:%.*]] = sub i12 0, [[X]]
; CHECK-NEXT: call void @use12(i12 [[SUB]])
; CHECK-NEXT: [[TMP1:%.*]] = add i12 [[X]], -1
; CHECK-NEXT: [[ADD:%.*]] = and i12 [[TMP1]], [[X]]
; CHECK-NEXT: ret i12 [[ADD]]
;
%x = mul i12 %p, %p ; thwart complexity-based canonicalization
%sub = sub i12 0, %x
call void @use12(i12 %sub) ; extra use of sub
%or = or i12 %sub, %x
%add = add i12 %or, %x
ret i12 %add
}
define i8 @add_or_sub_comb_i8_negative_y_sub(i8 %x, i8 %y) {
; CHECK-LABEL: @add_or_sub_comb_i8_negative_y_sub(
; CHECK-NEXT: [[SUB:%.*]] = sub i8 0, [[Y:%.*]]
; CHECK-NEXT: [[OR:%.*]] = or i8 [[SUB]], [[X:%.*]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[OR]], [[X]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sub = sub i8 0, %y ; mismatch: y instead of x
%or = or i8 %sub, %x
%add = add i8 %or, %x
ret i8 %add
}
define i8 @add_or_sub_comb_i8_negative_y_or(i8 %x, i8 %y) {
; CHECK-LABEL: @add_or_sub_comb_i8_negative_y_or(
; CHECK-NEXT: [[SUB:%.*]] = sub i8 0, [[X:%.*]]
; CHECK-NEXT: [[OR:%.*]] = or i8 [[SUB]], [[Y:%.*]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[OR]], [[X]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sub = sub i8 0, %x
%or = or i8 %sub, %y ; mismatch: y instead of x
%add = add i8 %or, %x
ret i8 %add
}
define i8 @add_or_sub_comb_i8_negative_y_add(i8 %x, i8 %y) {
; CHECK-LABEL: @add_or_sub_comb_i8_negative_y_add(
; CHECK-NEXT: [[SUB:%.*]] = sub i8 0, [[X:%.*]]
; CHECK-NEXT: [[OR:%.*]] = or i8 [[SUB]], [[X]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[OR]], [[Y:%.*]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sub = sub i8 0, %x
%or = or i8 %sub, %x
%add = add i8 %or, %y ; mismatch: y instead of x
ret i8 %add
}
define i8 @add_or_sub_comb_i8_negative_xor_instead_or(i8 %x) {
; CHECK-LABEL: @add_or_sub_comb_i8_negative_xor_instead_or(
; CHECK-NEXT: [[SUB:%.*]] = sub i8 0, [[X:%.*]]
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[SUB]], [[X]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sub = sub i8 0, %x
%xor = xor i8 %sub, %x ; mismatch: xor instead of or
%add = add i8 %xor, %x
ret i8 %add
}
define i16 @add_or_sub_comb_i16_negative_sub_no_negate(i16 %x) {
; CHECK-LABEL: @add_or_sub_comb_i16_negative_sub_no_negate(
; CHECK-NEXT: [[SUB:%.*]] = sub i16 1, [[X:%.*]]
; CHECK-NEXT: [[OR:%.*]] = or i16 [[SUB]], [[X]]
; CHECK-NEXT: [[ADD:%.*]] = add i16 [[OR]], [[X]]
; CHECK-NEXT: ret i16 [[ADD]]
;
%sub = sub i16 1, %x ; mismatch: sub isn't a negate
%or = or i16 %sub, %x
%add = add i16 %or, %x
ret i16 %add
}
define i2 @add_or_sub_comb_i2_negative_multiuse_only_or(i2 %p) {
; CHECK-LABEL: @add_or_sub_comb_i2_negative_multiuse_only_or(
; CHECK-NEXT: [[X:%.*]] = mul i2 [[P:%.*]], [[P]]
; CHECK-NEXT: [[SUB:%.*]] = sub i2 0, [[X]]
; CHECK-NEXT: [[OR:%.*]] = or i2 [[X]], [[SUB]]
; CHECK-NEXT: call void @use2(i2 [[OR]])
; CHECK-NEXT: [[ADD:%.*]] = add i2 [[OR]], [[X]]
; CHECK-NEXT: ret i2 [[ADD]]
;
%x = mul i2 %p, %p ; thwart complexity-based canonicalization
%sub = sub i2 0, %x
%or = or i2 %sub, %x
call void @use2(i2 %or) ; extra use of or
%add = add i2 %or, %x
ret i2 %add
}
define i19 @add_or_sub_comb_i19_negative_multiuse_both(i19 %p) {
; CHECK-LABEL: @add_or_sub_comb_i19_negative_multiuse_both(
; CHECK-NEXT: [[X:%.*]] = mul i19 [[P:%.*]], [[P]]
; CHECK-NEXT: [[SUB:%.*]] = sub i19 0, [[X]]
; CHECK-NEXT: call void @use19(i19 [[SUB]])
; CHECK-NEXT: [[OR:%.*]] = or i19 [[X]], [[SUB]]
; CHECK-NEXT: call void @use19(i19 [[OR]])
; CHECK-NEXT: [[ADD:%.*]] = add i19 [[OR]], [[X]]
; CHECK-NEXT: ret i19 [[ADD]]
;
%x = mul i19 %p, %p ; thwart complexity-based canonicalization
%sub = sub i19 0, %x
call void @use19(i19 %sub) ; extra use of sub
%or = or i19 %sub, %x
call void @use19(i19 %or) ; extra use of or
%add = add i19 %or, %x
ret i19 %add
}
|