Skip to content

Commit f744723

Browse files
committed
[X86] combineXor - limit fold to non-opaque constants (PR50254)
Ensure we don't try to fold when one might be an opaque constant - the constant fold will fail and then the reverse fold will happen in DAGCombine.....
1 parent 2819009 commit f744723

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46998,15 +46998,17 @@ static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
4699846998
// Fold xor(truncate(xor(x,c1)),c2) -> xor(truncate(x),xor(truncate(c1),c2))
4699946999
// TODO: Under what circumstances could this be performed in DAGCombine?
4700047000
if ((N0.getOpcode() == ISD::TRUNCATE || N0.getOpcode() == ISD::ZERO_EXTEND) &&
47001-
N0.getOperand(0).getOpcode() == N->getOpcode() &&
47002-
isa<ConstantSDNode>(N1) &&
47003-
isa<ConstantSDNode>(N0.getOperand(0).getOperand(1))) {
47004-
SDLoc DL(N);
47001+
N0.getOperand(0).getOpcode() == N->getOpcode()) {
4700547002
SDValue TruncExtSrc = N0.getOperand(0);
47006-
SDValue LHS = DAG.getZExtOrTrunc(TruncExtSrc.getOperand(0), DL, VT);
47007-
SDValue RHS = DAG.getZExtOrTrunc(TruncExtSrc.getOperand(1), DL, VT);
47008-
return DAG.getNode(ISD::XOR, DL, VT, LHS,
47009-
DAG.getNode(ISD::XOR, DL, VT, RHS, N1));
47003+
auto *N1C = dyn_cast<ConstantSDNode>(N1);
47004+
auto *N001C = dyn_cast<ConstantSDNode>(TruncExtSrc.getOperand(1));
47005+
if (N1C && !N1C->isOpaque() && N001C && !N001C->isOpaque()) {
47006+
SDLoc DL(N);
47007+
SDValue LHS = DAG.getZExtOrTrunc(TruncExtSrc.getOperand(0), DL, VT);
47008+
SDValue RHS = DAG.getZExtOrTrunc(TruncExtSrc.getOperand(1), DL, VT);
47009+
return DAG.getNode(ISD::XOR, DL, VT, LHS,
47010+
DAG.getNode(ISD::XOR, DL, VT, RHS, N1));
47011+
}
4701047012
}
4701147013

4701247014
if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, Subtarget))

llvm/test/CodeGen/X86/pr50254.ll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86
3+
; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64
4+
5+
@d.e = external dso_local unnamed_addr global i32, align 4
6+
7+
define void @PR50254() {
8+
; X86-LABEL: PR50254:
9+
; X86: # %bb.0: # %entry
10+
; X86-NEXT: movswl d.e, %eax
11+
; X86-NEXT: xorl %ecx, %ecx
12+
; X86-NEXT: testb %cl, %cl
13+
; X86-NEXT: jne .LBB0_2
14+
; X86-NEXT: # %bb.1: # %for.end
15+
; X86-NEXT: movw %ax, d.e
16+
; X86-NEXT: .LBB0_2: # %for.body.1
17+
; X86-NEXT: retl
18+
;
19+
; X64-LABEL: PR50254:
20+
; X64: # %bb.0: # %entry
21+
; X64-NEXT: movswq {{.*}}(%rip), %rax
22+
; X64-NEXT: xorl %ecx, %ecx
23+
; X64-NEXT: testb %cl, %cl
24+
; X64-NEXT: jne .LBB0_2
25+
; X64-NEXT: # %bb.1: # %for.end
26+
; X64-NEXT: movw %ax, {{.*}}(%rip)
27+
; X64-NEXT: .LBB0_2: # %for.body.1
28+
; X64-NEXT: retq
29+
entry:
30+
%load = load i16, i16* bitcast (i32* @d.e to i16*), align 4
31+
%xor1 = xor i16 %load, 0
32+
%xor2 = xor i64 undef, 3821908120
33+
%xor3 = xor i16 %load, -1
34+
%xor4 = sext i16 %xor3 to i64
35+
%xor5 = and i64 %xor4, 4294967295
36+
%xor6 = xor i64 %xor5, 3821908120
37+
br label %for.body
38+
39+
for.body: ; preds = %entry
40+
br i1 undef, label %for.end, label %for.body.1
41+
42+
for.end: ; preds = %for.body
43+
store i16 %xor1, i16* bitcast (i32* @d.e to i16*), align 4
44+
ret void
45+
46+
for.body.1: ; preds = %for.body
47+
%add.1 = add i64 %xor6, undef
48+
ret void
49+
}

0 commit comments

Comments
 (0)