Skip to content

Commit c511e1a

Browse files
authored
[InstCombine] Preserve nneg in foldLogicCastConstant (#157865)
This patch makes use of the new public helper function to preserve nneg in `foldLogicCastConstant`.
1 parent b574e63 commit c511e1a

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,10 +1801,14 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast,
18011801
Value *X;
18021802
auto &DL = IC.getDataLayout();
18031803
if (match(Cast, m_OneUse(m_ZExt(m_Value(X))))) {
1804-
if (Constant *TruncC = getLosslessUnsignedTrunc(C, SrcTy, DL)) {
1804+
PreservedCastFlags Flags;
1805+
if (Constant *TruncC = getLosslessUnsignedTrunc(C, SrcTy, DL, &Flags)) {
18051806
// LogicOpc (zext X), C --> zext (LogicOpc X, C)
18061807
Value *NewOp = IC.Builder.CreateBinOp(LogicOpc, X, TruncC);
1807-
return new ZExtInst(NewOp, DestTy);
1808+
auto *ZExt = new ZExtInst(NewOp, DestTy);
1809+
ZExt->setNonNeg(Flags.NNeg);
1810+
ZExt->andIRFlags(Cast);
1811+
return ZExt;
18081812
}
18091813
}
18101814

llvm/test/Transforms/InstCombine/or.ll

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,3 +2047,69 @@ define i1 @or_truncs(i8 %x) {
20472047
%or1 = or i1 %trunc1, %trunc2
20482048
ret i1 %or1
20492049
}
2050+
2051+
define i32 @or_zext_constant(i8 %a) {
2052+
; CHECK-LABEL: @or_zext_constant(
2053+
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 1
2054+
; CHECK-NEXT: [[AND:%.*]] = zext i8 [[TMP1]] to i32
2055+
; CHECK-NEXT: ret i32 [[AND]]
2056+
;
2057+
%zext = zext i8 %a to i32
2058+
%or = or i32 %zext, 1
2059+
ret i32 %or
2060+
}
2061+
2062+
define i32 @or_zext_minus_constant(i8 %a) {
2063+
; CHECK-LABEL: @or_zext_minus_constant(
2064+
; CHECK-NEXT: [[OR:%.*]] = zext i8 [[TMP1:%.*]] to i32
2065+
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[OR]], -9
2066+
; CHECK-NEXT: ret i32 [[OR1]]
2067+
;
2068+
%zext = zext i8 %a to i32
2069+
%or = or i32 %zext, -9
2070+
ret i32 %or
2071+
}
2072+
2073+
define i32 @or_zext_nneg_constant(i8 %a) {
2074+
; CHECK-LABEL: @or_zext_nneg_constant(
2075+
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 9
2076+
; CHECK-NEXT: [[AND:%.*]] = zext nneg i8 [[TMP1]] to i32
2077+
; CHECK-NEXT: ret i32 [[AND]]
2078+
;
2079+
%zext = zext nneg i8 %a to i32
2080+
%or = or i32 %zext, 9
2081+
ret i32 %or
2082+
}
2083+
2084+
define <4 x i32> @or_zext_nneg_constant_splat(<4 x i8> %a) {
2085+
; CHECK-LABEL: @or_zext_nneg_constant_splat(
2086+
; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 9)
2087+
; CHECK-NEXT: [[OR:%.*]] = zext nneg <4 x i8> [[TMP1]] to <4 x i32>
2088+
; CHECK-NEXT: ret <4 x i32> [[OR]]
2089+
;
2090+
%zext = zext nneg <4 x i8> %a to <4 x i32>
2091+
%or = or <4 x i32> %zext, splat (i32 9)
2092+
ret <4 x i32> %or
2093+
}
2094+
2095+
define i32 @or_zext_nneg_minus_constant(i8 %a) {
2096+
; CHECK-LABEL: @or_zext_nneg_minus_constant(
2097+
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], -9
2098+
; CHECK-NEXT: [[ZEXT:%.*]] = sext i8 [[TMP1]] to i32
2099+
; CHECK-NEXT: ret i32 [[ZEXT]]
2100+
;
2101+
%zext = zext nneg i8 %a to i32
2102+
%or = or i32 %zext, -9
2103+
ret i32 %or
2104+
}
2105+
2106+
define <4 x i32> @or_zext_nneg_minus_constant_splat(<4 x i8> %a) {
2107+
; CHECK-LABEL: @or_zext_nneg_minus_constant_splat(
2108+
; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 -9)
2109+
; CHECK-NEXT: [[OR:%.*]] = sext <4 x i8> [[TMP1]] to <4 x i32>
2110+
; CHECK-NEXT: ret <4 x i32> [[OR]]
2111+
;
2112+
%zext = zext nneg <4 x i8> %a to <4 x i32>
2113+
%or = or <4 x i32> %zext, splat (i32 -9)
2114+
ret <4 x i32> %or
2115+
}

0 commit comments

Comments
 (0)