Skip to content

Commit a22282b

Browse files
committed
[InstCombine] make icmp vector canonicalization safe for constant with undef elements
This is a fix for: https://bugs.llvm.org/show_bug.cgi?id=43730 ...and as shown there, we have existing test cases that show potential miscompiles. We could just bail out for vector constants that contain any undef elements, or we can do as shown here: allow the transform, but replace the undefs with a safe value. For most of the tests shown, this results in a full splat constant (no undefs) which is probably a win for further IR analysis because we conservatively don't match undefs in most cases. Codegen can probably recover these kinds of undef lanes via demanded elements analysis if that's profitable. Differential Revision: https://reviews.llvm.org/D69519
1 parent 98f3151 commit a22282b

8 files changed

+21
-9
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5167,6 +5167,7 @@ llvm::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
51675167
return WillIncrement ? !C->isMaxValue(IsSigned) : !C->isMinValue(IsSigned);
51685168
};
51695169

5170+
Constant *SafeReplacementConstant = nullptr;
51705171
if (auto *CI = dyn_cast<ConstantInt>(C)) {
51715172
// Bail out if the constant can't be safely incremented/decremented.
51725173
if (!ConstantIsOk(CI))
@@ -5186,12 +5187,23 @@ llvm::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred,
51865187
auto *CI = dyn_cast<ConstantInt>(Elt);
51875188
if (!CI || !ConstantIsOk(CI))
51885189
return llvm::None;
5190+
5191+
if (!SafeReplacementConstant)
5192+
SafeReplacementConstant = CI;
51895193
}
51905194
} else {
51915195
// ConstantExpr?
51925196
return llvm::None;
51935197
}
51945198

5199+
// It may not be safe to change a compare predicate in the presence of
5200+
// undefined elements, so replace those elements with the first safe constant
5201+
// that we found.
5202+
if (C->containsUndefElement()) {
5203+
assert(SafeReplacementConstant && "Replacement constant not set");
5204+
C = Constant::replaceUndefsWith(C, SafeReplacementConstant);
5205+
}
5206+
51955207
CmpInst::Predicate NewPred = CmpInst::getFlippedStrictnessPredicate(Pred);
51965208

51975209
// Increment or decrement the constant.

llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-eq-to-icmp-ule.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ define <2 x i1> @p2_vec_nonsplat_edgecase1(<2 x i8> %x) {
8282

8383
define <3 x i1> @p3_vec_splat_undef(<3 x i8> %x) {
8484
; CHECK-LABEL: @p3_vec_splat_undef(
85-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X:%.*]], <i8 4, i8 undef, i8 4>
85+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X:%.*]], <i8 4, i8 4, i8 4>
8686
; CHECK-NEXT: ret <3 x i1> [[TMP1]]
8787
;
8888
%tmp0 = and <3 x i8> %x, <i8 3, i8 undef, i8 3>

llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sge-to-icmp-sle.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ define <2 x i1> @p2_vec_nonsplat_edgecase(<2 x i8> %x) {
6161

6262
define <3 x i1> @p3_vec_splat_undef(<3 x i8> %x) {
6363
; CHECK-LABEL: @p3_vec_splat_undef(
64-
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i8> [[X:%.*]], <i8 4, i8 undef, i8 4>
64+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i8> [[X:%.*]], <i8 4, i8 4, i8 4>
6565
; CHECK-NEXT: ret <3 x i1> [[TMP1]]
6666
;
6767
%tmp0 = and <3 x i8> %x, <i8 3, i8 undef, i8 3>

llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sle-to-icmp-sle.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ define <2 x i1> @p2_vec_nonsplat_edgecase() {
7676
define <3 x i1> @p3_vec_splat_undef() {
7777
; CHECK-LABEL: @p3_vec_splat_undef(
7878
; CHECK-NEXT: [[X:%.*]] = call <3 x i8> @gen3x8()
79-
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i8> [[X]], <i8 4, i8 undef, i8 4>
79+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i8> [[X]], <i8 4, i8 4, i8 4>
8080
; CHECK-NEXT: ret <3 x i1> [[TMP1]]
8181
;
8282
%x = call <3 x i8> @gen3x8()

llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-uge-to-icmp-ule.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ define <2 x i1> @p2_vec_nonsplat_edgecase1(<2 x i8> %x) {
8282

8383
define <3 x i1> @p3_vec_splat_undef(<3 x i8> %x) {
8484
; CHECK-LABEL: @p3_vec_splat_undef(
85-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X:%.*]], <i8 4, i8 undef, i8 4>
85+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X:%.*]], <i8 4, i8 4, i8 4>
8686
; CHECK-NEXT: ret <3 x i1> [[TMP1]]
8787
;
8888
%tmp0 = and <3 x i8> %x, <i8 3, i8 undef, i8 3>

llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-ule-to-icmp-ule.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ define <2 x i1> @p2_vec_nonsplat_edgecase1() {
9999
define <3 x i1> @p3_vec_splat_undef() {
100100
; CHECK-LABEL: @p3_vec_splat_undef(
101101
; CHECK-NEXT: [[X:%.*]] = call <3 x i8> @gen3x8()
102-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X]], <i8 4, i8 undef, i8 4>
102+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[X]], <i8 4, i8 4, i8 4>
103103
; CHECK-NEXT: ret <3 x i1> [[TMP1]]
104104
;
105105
%x = call <3 x i8> @gen3x8()

llvm/test/Transforms/InstCombine/icmp-vec.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ define <2 x i1> @PR27756_1(<2 x i8> %a) {
181181

182182
define <3 x i1> @PR27756_2(<3 x i8> %a) {
183183
; CHECK-LABEL: @PR27756_2(
184-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <3 x i8> [[A:%.*]], <i8 43, i8 undef, i8 1>
184+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <3 x i8> [[A:%.*]], <i8 43, i8 43, i8 1>
185185
; CHECK-NEXT: ret <3 x i1> [[CMP]]
186186
;
187187
%cmp = icmp sle <3 x i8> %a, <i8 42, i8 undef, i8 0>
@@ -190,7 +190,7 @@ define <3 x i1> @PR27756_2(<3 x i8> %a) {
190190

191191
define <3 x i1> @PR27756_3(<3 x i8> %a) {
192192
; CHECK-LABEL: @PR27756_3(
193-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i8> [[A:%.*]], <i8 undef, i8 0, i8 41>
193+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i8> [[A:%.*]], <i8 0, i8 0, i8 41>
194194
; CHECK-NEXT: ret <3 x i1> [[CMP]]
195195
;
196196
%cmp = icmp sge <3 x i8> %a, <i8 undef, i8 1, i8 42>

llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ define <2 x i32> @p7_vec_splat_sgt(<2 x i32> %x, <2 x i32> %y) {
106106

107107
define <2 x i32> @p8_vec_nonsplat_undef0(<2 x i32> %x, <2 x i32> %y) {
108108
; CHECK-LABEL: @p8_vec_nonsplat_undef0(
109-
; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 undef>
109+
; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
110110
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
111111
; CHECK-NEXT: ret <2 x i32> [[R]]
112112
;
@@ -126,7 +126,7 @@ define <2 x i32> @p9_vec_nonsplat_undef1(<2 x i32> %x, <2 x i32> %y) {
126126
}
127127
define <2 x i32> @p10_vec_nonsplat_undef2(<2 x i32> %x, <2 x i32> %y) {
128128
; CHECK-LABEL: @p10_vec_nonsplat_undef2(
129-
; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 undef>
129+
; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
130130
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 undef>, <2 x i32> [[Y:%.*]]
131131
; CHECK-NEXT: ret <2 x i32> [[R]]
132132
;

0 commit comments

Comments
 (0)