Skip to content

Commit 316c076

Browse files
authored
[X86] Fix X86 conditional load/store optimization for non-constant operands (#163353)
This PR fixes a bug in combineX86CloadCstore where an optimization was being applied too broadly, causing incorrect code generation. Without any assumptions about `X` this transformation is only valid when `Y` is a non zero power of two/single-bit mask. ```cpp // res, flags2 = sub 0, (and (xor X, -1), Y) // cload/cstore ..., cond_ne, flag2 // -> // res, flags2 = sub 0, (and X, Y) // cload/cstore ..., cond_e, flag2 ``` We can restrict the optimization to most important case, so only apply when `llvm::isOneConstant(Op1.getOperand(1))`. It might be not trivial to find code that creates a SelectionDag with other values of `Y`. Basline test: llvm/llvm-project#163354
1 parent deaf7b9 commit 316c076

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58342,11 +58342,12 @@ static SDValue combineX86CloadCstore(SDNode *N, SelectionDAG &DAG) {
5834258342
} else if (Op1.getOpcode() == ISD::AND && Sub.getValue(0).use_empty()) {
5834358343
SDValue Src = Op1;
5834458344
SDValue Op10 = Op1.getOperand(0);
58345-
if (Op10.getOpcode() == ISD::XOR && isAllOnesConstant(Op10.getOperand(1))) {
58346-
// res, flags2 = sub 0, (and (xor X, -1), Y)
58345+
if (Op10.getOpcode() == ISD::XOR && isAllOnesConstant(Op10.getOperand(1)) &&
58346+
llvm::isOneConstant(Op1.getOperand(1))) {
58347+
// res, flags2 = sub 0, (and (xor X, -1), 1)
5834758348
// cload/cstore ..., cond_ne, flag2
5834858349
// ->
58349-
// res, flags2 = sub 0, (and X, Y)
58350+
// res, flags2 = sub 0, (and X, 1)
5835058351
// cload/cstore ..., cond_e, flag2
5835158352
Src = DAG.getNode(ISD::AND, DL, Op1.getValueType(), Op10.getOperand(0),
5835258353
Op1.getOperand(1));

llvm/test/CodeGen/X86/apx/cf.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,10 @@ define void @and_cond(i32 %a, i1 %b) {
235235
; CHECK: # %bb.0:
236236
; CHECK-NEXT: testl %edi, %edi
237237
; CHECK-NEXT: setg %al
238+
; CHECK-NEXT: notb %sil
238239
; CHECK-NEXT: xorl %ecx, %ecx
239240
; CHECK-NEXT: testb %al, %sil
240-
; CHECK-NEXT: cfcmovel %ecx, 0
241+
; CHECK-NEXT: cfcmovnel %ecx, 0
241242
; CHECK-NEXT: retq
242243
%is_pos = icmp sgt i32 %a, 0
243244
%not_b = xor i1 %b, true

0 commit comments

Comments
 (0)