diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1796,6 +1796,12 @@ return replaceInstUsesWith(I, V); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + // (freeze undef)&A -> 0 + if (match(Op0, m_OneUse(m_Freeze(m_Undef()))) || + match(Op1, m_OneUse(m_Freeze(m_Undef())))) + return replaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); + const APInt *C; if (match(Op1, m_APInt(C))) { Value *X, *Y; @@ -2612,6 +2618,12 @@ // (A & C)|(B & D) Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + // (freeze undef)|A -> -1 + if (match(Op0, m_OneUse(m_Freeze(m_Undef()))) || + match(Op1, m_OneUse(m_Freeze(m_Undef())))) + return replaceInstUsesWith(I, Constant::getAllOnesValue(Op0->getType())); + Value *A, *B, *C, *D; if (match(Op0, m_And(m_Value(A), m_Value(C))) && match(Op1, m_And(m_Value(B), m_Value(D)))) { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2548,6 +2548,11 @@ } } + // select (freeze undef), X, Y -> X + if (match(CondVal, m_OneUse(m_Freeze(m_Undef())))) + return replaceInstUsesWith(SI, + isa(FalseVal) ? FalseVal : TrueVal); + if (Value *V = SimplifySelectInst(CondVal, TrueVal, FalseVal, SQ.getWithInstruction(&SI))) return replaceInstUsesWith(SI, V); diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll --- a/llvm/test/Transforms/InstCombine/and.ll +++ b/llvm/test/Transforms/InstCombine/and.ll @@ -934,3 +934,27 @@ %r = and <2 x i59> %s, ; -1 u>> 5 == 0x3f_ffff_ffff_ffff ret <2 x i59> %r } + +define i32 @and_freeze_undef(i32 %x) { +; CHECK-LABEL: @and_freeze_undef( +; CHECK-NEXT: ret i32 0 +; + %f = freeze i32 undef + %res = and i32 %x, %f + ret i32 %res +} + +declare void @use_i32(i32) + +define i32 @and_freeze_undef_multipleuses(i32 %x) { +; CHECK-LABEL: @and_freeze_undef_multipleuses( +; CHECK-NEXT: [[F:%.*]] = freeze i32 undef +; CHECK-NEXT: [[RES:%.*]] = and i32 [[F]], [[X:%.*]] +; CHECK-NEXT: call void @use_i32(i32 [[F]]) +; CHECK-NEXT: ret i32 [[RES]] +; + %f = freeze i32 undef + %res = and i32 %x, %f + call void @use_i32(i32 %f) + ret i32 %res +} diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll --- a/llvm/test/Transforms/InstCombine/or.ll +++ b/llvm/test/Transforms/InstCombine/or.ll @@ -876,3 +876,27 @@ %conv8 = zext i1 %t5 to i32 ret i32 %conv8 } + +define i32 @or_freeze_undef(i32 %x) { +; CHECK-LABEL: @or_freeze_undef( +; CHECK-NEXT: ret i32 -1 +; + %f = freeze i32 undef + %res = or i32 %x, %f + ret i32 %res +} + +declare void @use_i32(i32) + +define i32 @or_freeze_undef_multipleuses(i32 %x) { +; CHECK-LABEL: @or_freeze_undef_multipleuses( +; CHECK-NEXT: [[F:%.*]] = freeze i32 undef +; CHECK-NEXT: [[RES:%.*]] = or i32 [[F]], [[X:%.*]] +; CHECK-NEXT: call void @use_i32(i32 [[F]]) +; CHECK-NEXT: ret i32 [[RES]] +; + %f = freeze i32 undef + %res = or i32 %x, %f + call void @use_i32(i32 %f) + ret i32 %res +} diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -2490,9 +2490,7 @@ define i8 @cond_freeze(i8 %x, i8 %y) { ; CHECK-LABEL: @cond_freeze( -; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 undef -; CHECK-NEXT: [[S:%.*]] = select i1 [[COND_FR]], i8 [[X:%.*]], i8 [[Y:%.*]] -; CHECK-NEXT: ret i8 [[S]] +; CHECK-NEXT: ret i8 [[X:%.*]] ; %cond.fr = freeze i1 undef %s = select i1 %cond.fr, i8 %x, i8 %y @@ -2501,9 +2499,7 @@ define i8 @cond_freeze2(i8 %x, i8 %y) { ; CHECK-LABEL: @cond_freeze2( -; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 undef -; CHECK-NEXT: [[S:%.*]] = select i1 [[COND_FR]], i8 [[X:%.*]], i8 1 -; CHECK-NEXT: ret i8 [[S]] +; CHECK-NEXT: ret i8 1 ; %cond.fr = freeze i1 undef %s = select i1 %cond.fr, i8 %x, i8 1