[llvm-branch-commits] [clang] 162642b - Revert "[ConstantFold] Fold more operations to poison"
Author: Juneyoung Lee Date: 2021-02-04T01:22:55+09:00 New Revision: 162642bec0df760b27e66cfff046b40f1dfd2713 URL: https://github.com/llvm/llvm-project/commit/162642bec0df760b27e66cfff046b40f1dfd2713 DIFF: https://github.com/llvm/llvm-project/commit/162642bec0df760b27e66cfff046b40f1dfd2713.diff LOG: Revert "[ConstantFold] Fold more operations to poison" This reverts commit 53040a968dc2ff20931661e55f05da2ef8b964a0 due to its bad interaction with select i1 -> and/or i1 transformation. This fixes: https://bugs.llvm.org/show_bug.cgi?id=49005 https://bugs.llvm.org/show_bug.cgi?id=48435 (cherry picked from commit 06829034ca64b8c83a5b20d8abe5ddbfe7af0004) Added: Modified: clang/test/Frontend/fixed_point_unary.c llvm/lib/IR/ConstantFold.cpp llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fold-binop-select.ll llvm/test/Transforms/InstCombine/apint-shift.ll llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll llvm/test/Transforms/InstCombine/canonicalize-shl-lshr-to-masking.ll llvm/test/Transforms/InstCombine/icmp.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-a.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-c.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-e.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-a.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-c.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-e.ll llvm/test/Transforms/InstCombine/select-of-bittest.ll llvm/test/Transforms/InstCombine/shift-add-inseltpoison.ll llvm/test/Transforms/InstCombine/shift-add.ll llvm/test/Transforms/InstSimplify/ConstProp/InsertElement-inseltpoison.ll llvm/test/Transforms/InstSimplify/ConstProp/InsertElement.ll llvm/test/Transforms/InstSimplify/ConstProp/cast.ll llvm/test/Transforms/InstSimplify/ConstProp/poison.ll llvm/test/Transforms/InstSimplify/ConstProp/shift.ll llvm/test/Transforms/InstSimplify/ConstProp/vector-undef-elts-inseltpoison.ll llvm/test/Transforms/InstSimplify/ConstProp/vector-undef-elts.ll llvm/test/Transforms/InstSimplify/ConstProp/vscale-inseltpoison.ll llvm/test/Transforms/InstSimplify/ConstProp/vscale.ll llvm/test/Transforms/InstSimplify/div.ll llvm/test/Transforms/InstSimplify/rem.ll llvm/test/Transforms/InstSimplify/undef.ll llvm/test/Transforms/SROA/phi-gep.ll llvm/test/Transforms/SROA/select-gep.ll llvm/test/Transforms/VectorCombine/X86/insert-binop-inseltpoison.ll llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll llvm/test/Transforms/VectorCombine/X86/insert-binop.ll llvm/unittests/IR/ConstantsTest.cpp Removed: diff --git a/clang/test/Frontend/fixed_point_unary.c b/clang/test/Frontend/fixed_point_unary.c index 6ce760daba11..849e38a94bc4 100644 --- a/clang/test/Frontend/fixed_point_unary.c +++ b/clang/test/Frontend/fixed_point_unary.c @@ -90,7 +90,7 @@ void inc_usa() { // SIGNED-LABEL: @inc_uf( // SIGNED-NEXT: entry: // SIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @uf, align 2 -// SIGNED-NEXT:[[TMP1:%.*]] = add i16 [[TMP0]], poison +// SIGNED-NEXT:[[TMP1:%.*]] = add i16 [[TMP0]], undef // SIGNED-NEXT:store i16 [[TMP1]], i16* @uf, align 2 // SIGNED-NEXT:ret void // @@ -271,7 +271,7 @@ void dec_usa() { // SIGNED-LABEL: @dec_uf( // SIGNED-NEXT: entry: // SIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @uf, align 2 -// SIGNED-NEXT:[[TMP1:%.*]] = sub i16 [[TMP0]], poison +// SIGNED-NEXT:[[TMP1:%.*]] = sub i16 [[TMP0]], undef // SIGNED-NEXT:store i16 [[TMP1]], i16* @uf, align 2 // SIGNED-NEXT:ret void // diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 03cb108cc485..95dd55237e5f 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -630,7 +630,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored)) { // Undefined behavior invoked - the destination type can't represent // the input constant. -return PoisonValue::get(DestTy); +return UndefVal
[llvm-branch-commits] [llvm] 76643c4 - [LangRef] State that a nocapture pointer cannot be returned
Author: Juneyoung Lee Date: 2021-01-13T09:30:54+09:00 New Revision: 76643c48cdddfa220680f1ab4a83829bd83faa7a URL: https://github.com/llvm/llvm-project/commit/76643c48cdddfa220680f1ab4a83829bd83faa7a DIFF: https://github.com/llvm/llvm-project/commit/76643c48cdddfa220680f1ab4a83829bd83faa7a.diff LOG: [LangRef] State that a nocapture pointer cannot be returned This is a small patch stating that a nocapture pointer cannot be returned. Discussed in D93189. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D94386 Added: Modified: llvm/docs/LangRef.rst Removed: diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index ab5287014683..854c72191da2 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1193,7 +1193,8 @@ Currently, only the following parameter attributes are defined: ``nocapture`` This indicates that the callee does not make any copies of the -pointer that outlive the callee itself. This is not a valid +pointer that outlive the callee itself in any form such as a pointer stored +in the memory or as a return value. This is not a valid attribute for return values. Addresses used in volatile operations are considered to be captured. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 25eb7b0 - [DAGCombiner] Fold BRCOND(FREEZE(COND)) to BRCOND(COND)
Author: Juneyoung Lee Date: 2021-01-13T09:36:52+09:00 New Revision: 25eb7b08ba77a0b7c9c938490444bb8b5121233c URL: https://github.com/llvm/llvm-project/commit/25eb7b08ba77a0b7c9c938490444bb8b5121233c DIFF: https://github.com/llvm/llvm-project/commit/25eb7b08ba77a0b7c9c938490444bb8b5121233c.diff LOG: [DAGCombiner] Fold BRCOND(FREEZE(COND)) to BRCOND(COND) This patch resolves the suboptimal codegen described in http://llvm.org/pr47873 . When CodeGenPrepare lowers select into a conditional branch, a freeze instruction is inserted. It is then translated to `BRCOND(FREEZE(SETCC))` in SelDag. The `FREEZE` in the middle of `SETCC` and `BRCOND` was causing a suboptimal code generation however. This patch adds `BRCOND(FREEZE(cond))` -> `BRCOND(cond)` fold to DAGCombiner to remove the `FREEZE`. To make this optimization sound, `BRCOND(UNDEF)` simply should nondeterministically jump to the branch or not, rather than raising UB. It wasn't clear what happens when the condition was undef according to the comments in ISDOpcodes.h, however. I updated the comments of `BRCOND` to make it explicit (as well as `BR_CC`, which is also a conditional branch instruction). Note that it diverges from the semantics of `br` instruction in IR, which is explicitly UB. Since the UB semantics was necessary to explain optimizations that use branching conditions, and SelDag doesn't seem to have such optimization, I think this divergence is okay. Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D92015 Added: Modified: llvm/include/llvm/CodeGen/ISDOpcodes.h llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/test/CodeGen/X86/select-prof-codegen.ll Removed: diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index 5b35266dcbaa..5358b15437cc 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -890,13 +890,18 @@ enum NodeType { /// BRCOND - Conditional branch. The first operand is the chain, the /// second is the condition, the third is the block to branch to if the /// condition is true. If the type of the condition is not i1, then the - /// high bits must conform to getBooleanContents. + /// high bits must conform to getBooleanContents. If the condition is undef, + /// it nondeterministically jumps to the block. + /// TODO: Its semantics w.r.t undef requires further discussion; we need to + /// make it sure that it is consistent with optimizations in MIR & the + /// meaning of IMPLICIT_DEF. See https://reviews.llvm.org/D92015 BRCOND, /// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in /// that the condition is represented as condition code, and two nodes to /// compare, rather than as a combined SetCC node. The operands in order - /// are chain, cc, lhs, rhs, block to branch to if condition is true. + /// are chain, cc, lhs, rhs, block to branch to if condition is true. If + /// condition is undef, it nondeterministically jumps to the block. BR_CC, /// INLINEASM - Represents an inline asm block. This node always has two diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9f55bd03fbe4..5d9bb4e4a98b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14548,6 +14548,13 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) { SDValue N1 = N->getOperand(1); SDValue N2 = N->getOperand(2); + // BRCOND(FREEZE(cond)) is equivalent to BRCOND(cond) (both are + // nondeterministic jumps). + if (N1->getOpcode() == ISD::FREEZE && N1.hasOneUse()) { +return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other, Chain, + N1->getOperand(0), N2); + } + // If N is a constant we could fold this into a fallthrough or unconditional // branch. However that doesn't happen very often in normal code, because // Instcombine/SimplifyCFG should have handled the available opportunities. diff --git a/llvm/test/CodeGen/X86/select-prof-codegen.ll b/llvm/test/CodeGen/X86/select-prof-codegen.ll index 22f7d728847b..5ae09afd239e 100644 --- a/llvm/test/CodeGen/X86/select-prof-codegen.ll +++ b/llvm/test/CodeGen/X86/select-prof-codegen.ll @@ -1,15 +1,13 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -; TODO: Compiling the select should not create 'seta - testb $1 - jump' sequence. +; Compiling the select should not create 'seta - testb $1 - jump' sequence. define i32 @f(i32 %x, i32 %y) { ; CHECK-LABEL: f: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT:movl %edi, %eax ; CHECK-NEXT:cmpl %esi, %edi -; CHECK-NEXT:seta %cl -; CHECK-NEXT:testb $1, %cl -; CHECK-NEXT:jne .LBB0_2 +; CHECK-NEXT:ja .LBB0_2
[llvm-branch-commits] [llvm] b664bef - [InstCombine] Add a test file that contains safe select transforms (NFC)
Author: Juneyoung Lee Date: 2021-01-16T19:27:43+09:00 New Revision: b664bef2ad9a7d32192b9351f39a222332da8c6d URL: https://github.com/llvm/llvm-project/commit/b664bef2ad9a7d32192b9351f39a222332da8c6d DIFF: https://github.com/llvm/llvm-project/commit/b664bef2ad9a7d32192b9351f39a222332da8c6d.diff LOG: [InstCombine] Add a test file that contains safe select transforms (NFC) Added: llvm/test/Transforms/InstCombine/select-safe-transforms.ll Modified: Removed: diff --git a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll new file mode 100644 index ..48067bf9d67f --- /dev/null +++ b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll @@ -0,0 +1,76 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine-unsafe-select-transform=0 -instcombine -S | FileCheck %s + +define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) { +; CHECK-LABEL: @cond_eq_and( +; CHECK-NEXT:[[COND:%.*]] = icmp eq i8 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT:[[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] +; CHECK-NEXT:[[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false +; CHECK-NEXT:ret i1 [[RES]] +; + %cond = icmp eq i8 %X, %C + %lhs = icmp ult i8 %X, %Y + %res = select i1 %cond, i1 %lhs, i1 false + ret i1 %res +} + +define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) { +; CHECK-LABEL: @cond_eq_or( +; CHECK-NEXT:[[COND:%.*]] = icmp ne i8 [[X:%.*]], [[C:%.*]] +; CHECK-NEXT:[[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] +; CHECK-NEXT:[[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]] +; CHECK-NEXT:ret i1 [[RES]] +; + %cond = icmp ne i8 %X, %C + %lhs = icmp ult i8 %X, %Y + %res = select i1 %cond, i1 true, i1 %lhs + ret i1 %res +} + +define i1 @merge_and(i1 %X, i1 %Y) { +; CHECK-LABEL: @merge_and( +; CHECK-NEXT:[[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false +; CHECK-NEXT:[[RES:%.*]] = and i1 [[C]], [[X]] +; CHECK-NEXT:ret i1 [[RES]] +; + %c = select i1 %X, i1 %Y, i1 false + %res = and i1 %X, %c + ret i1 %res +} + +define i1 @merge_or(i1 %X, i1 %Y) { +; CHECK-LABEL: @merge_or( +; CHECK-NEXT:[[C:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] +; CHECK-NEXT:[[RES:%.*]] = or i1 [[C]], [[X]] +; CHECK-NEXT:ret i1 [[RES]] +; + %c = select i1 %X, i1 true, i1 %Y + %res = or i1 %X, %c + ret i1 %res +} + +define i1 @xor_and(i1 %c, i32 %X, i32 %Y) { +; CHECK-LABEL: @xor_and( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[C:%.*]], i1 [[COMP]], i1 false +; CHECK-NEXT:[[RES:%.*]] = xor i1 [[SEL]], true +; CHECK-NEXT:ret i1 [[RES]] +; + %comp = icmp ult i32 %X, %Y + %sel = select i1 %c, i1 %comp, i1 false + %res = xor i1 %sel, true + ret i1 %res +} + +define i1 @xor_or(i1 %c, i32 %X, i32 %Y) { +; CHECK-LABEL: @xor_or( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[COMP]] +; CHECK-NEXT:[[RES:%.*]] = xor i1 [[SEL]], true +; CHECK-NEXT:ret i1 [[RES]] +; + %comp = icmp ult i32 %X, %Y + %sel = select i1 %c, i1 true, i1 %comp + %res = xor i1 %sel, true + ret i1 %res +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] e0a979c - [InstCombine] Add more tests to select-safe-transforms.ll (NFC)
Author: Juneyoung Lee Date: 2021-01-16T19:49:12+09:00 New Revision: e0a979ccadd81c71d78be816e893dd1bcd6508ee URL: https://github.com/llvm/llvm-project/commit/e0a979ccadd81c71d78be816e893dd1bcd6508ee DIFF: https://github.com/llvm/llvm-project/commit/e0a979ccadd81c71d78be816e893dd1bcd6508ee.diff LOG: [InstCombine] Add more tests to select-safe-transforms.ll (NFC) Added: Modified: llvm/test/Transforms/InstCombine/select-safe-transforms.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll index 48067bf9d67f..b16985ba1b75 100644 --- a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll +++ b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll @@ -14,6 +14,19 @@ define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) { ret i1 %res } +define i1 @cond_eq_and_const(i8 %X, i8 %Y) { +; CHECK-LABEL: @cond_eq_and_const( +; CHECK-NEXT:[[COND:%.*]] = icmp eq i8 [[X:%.*]], 10 +; CHECK-NEXT:[[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] +; CHECK-NEXT:[[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false +; CHECK-NEXT:ret i1 [[RES]] +; + %cond = icmp eq i8 %X, 10 + %lhs = icmp ult i8 %X, %Y + %res = select i1 %cond, i1 %lhs, i1 false + ret i1 %res +} + define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) { ; CHECK-LABEL: @cond_eq_or( ; CHECK-NEXT:[[COND:%.*]] = icmp ne i8 [[X:%.*]], [[C:%.*]] @@ -27,6 +40,19 @@ define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) { ret i1 %res } +define i1 @cond_eq_or_const(i8 %X, i8 %Y) { +; CHECK-LABEL: @cond_eq_or_const( +; CHECK-NEXT:[[COND:%.*]] = icmp ne i8 [[X:%.*]], 10 +; CHECK-NEXT:[[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] +; CHECK-NEXT:[[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]] +; CHECK-NEXT:ret i1 [[RES]] +; + %cond = icmp ne i8 %X, 10 + %lhs = icmp ult i8 %X, %Y + %res = select i1 %cond, i1 true, i1 %lhs + ret i1 %res +} + define i1 @merge_and(i1 %X, i1 %Y) { ; CHECK-LABEL: @merge_and( ; CHECK-NEXT:[[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 2639c16 - [InstCombine] more tests for D94861 (NFC)
Author: Juneyoung Lee Date: 2021-01-18T11:12:52+09:00 New Revision: 2639c162b71f4b9e5c0ffefaa861fe915b73cb87 URL: https://github.com/llvm/llvm-project/commit/2639c162b71f4b9e5c0ffefaa861fe915b73cb87 DIFF: https://github.com/llvm/llvm-project/commit/2639c162b71f4b9e5c0ffefaa861fe915b73cb87.diff LOG: [InstCombine] more tests for D94861 (NFC) Added: Modified: llvm/test/Transforms/InstCombine/select-safe-transforms.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll index f6dfb672e7f2..48235863d9ff 100644 --- a/llvm/test/Transforms/InstCombine/select-safe-transforms.ll +++ b/llvm/test/Transforms/InstCombine/select-safe-transforms.ll @@ -88,6 +88,34 @@ define i1 @xor_and(i1 %c, i32 %X, i32 %Y) { ret i1 %res } +define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { +; CHECK-LABEL: @xor_and2( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> +; CHECK-NEXT:[[RES:%.*]] = xor <2 x i1> [[SEL]], +; CHECK-NEXT:ret <2 x i1> [[RES]] +; + %comp = icmp ult <2 x i32> %X, %Y + %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> + %res = xor <2 x i1> %sel, + ret <2 x i1> %res +} + +@glb = global i8 0 + +define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { +; CHECK-LABEL: @xor_and3( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> +; CHECK-NEXT:[[RES:%.*]] = xor <2 x i1> [[SEL]], +; CHECK-NEXT:ret <2 x i1> [[RES]] +; + %comp = icmp ult <2 x i32> %X, %Y + %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> + %res = xor <2 x i1> %sel, + ret <2 x i1> %res +} + define i1 @xor_or(i1 %c, i32 %X, i32 %Y) { ; CHECK-LABEL: @xor_or( ; CHECK-NEXT:[[COMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] @@ -100,3 +128,29 @@ define i1 @xor_or(i1 %c, i32 %X, i32 %Y) { %res = xor i1 %sel, true ret i1 %res } + +define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { +; CHECK-LABEL: @xor_or2( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> , <2 x i1> [[COMP]] +; CHECK-NEXT:[[RES:%.*]] = xor <2 x i1> [[SEL]], +; CHECK-NEXT:ret <2 x i1> [[RES]] +; + %comp = icmp ult <2 x i32> %X, %Y + %sel = select <2 x i1> %c, <2 x i1> , <2 x i1> %comp + %res = xor <2 x i1> %sel, + ret <2 x i1> %res +} + +define <2 x i1> @xor_or3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { +; CHECK-LABEL: @xor_or3( +; CHECK-NEXT:[[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> , <2 x i1> [[COMP]] +; CHECK-NEXT:[[RES:%.*]] = xor <2 x i1> [[SEL]], +; CHECK-NEXT:ret <2 x i1> [[RES]] +; + %comp = icmp ult <2 x i32> %X, %Y + %sel = select <2 x i1> %c, <2 x i1> , <2 x i1> %comp + %res = xor <2 x i1> %sel, + ret <2 x i1> %res +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 395c737 - [SimplifyCFG] Update SimplifyBranchOnICmpChain to recognize select form of and/or
Author: Juneyoung Lee Date: 2021-01-19T08:53:40+09:00 New Revision: 395c737d9fcefb0fb99ac6c524b1d47e697d31d6 URL: https://github.com/llvm/llvm-project/commit/395c737d9fcefb0fb99ac6c524b1d47e697d31d6 DIFF: https://github.com/llvm/llvm-project/commit/395c737d9fcefb0fb99ac6c524b1d47e697d31d6.diff LOG: [SimplifyCFG] Update SimplifyBranchOnICmpChain to recognize select form of and/or This patch teaches SimplifyCFG::SimplifyBranchOnICmpChain to understand select form of (x == C1 || x == C2 || ...) / (x != C1 && x != C2 && ...) and optimize them into switch if possible. D93065 has more context about the transition, including links to the list of optimizations being updated. Differential Revision: https://reviews.llvm.org/D93943 Added: Modified: llvm/lib/Transforms/Utils/SimplifyCFG.cpp llvm/test/Transforms/SimplifyCFG/switch_create.ll Removed: diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 7fe33fd3c759..a243a2e37950 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -692,7 +692,7 @@ struct ConstantComparesGatherer { /// vector. /// One "Extra" case is allowed to diff er from the other. void gather(Value *V) { -bool isEQ = (cast(V)->getOpcode() == Instruction::Or); +bool isEQ = match(V, m_LogicalOr(m_Value(), m_Value())); // Keep a stack (SmallVector for efficiency) for depth-first traversal SmallVector DFT; @@ -707,11 +707,14 @@ struct ConstantComparesGatherer { if (Instruction *I = dyn_cast(V)) { // If it is a || (or && depending on isEQ), process the operands. -if (I->getOpcode() == (isEQ ? Instruction::Or : Instruction::And)) { - if (Visited.insert(I->getOperand(1)).second) -DFT.push_back(I->getOperand(1)); - if (Visited.insert(I->getOperand(0)).second) -DFT.push_back(I->getOperand(0)); +Value *Op0, *Op1; +if (isEQ ? match(I, m_LogicalOr(m_Value(Op0), m_Value(Op1))) + : match(I, m_LogicalAnd(m_Value(Op0), m_Value(Op1 { + if (Visited.insert(Op1).second) +DFT.push_back(Op1); + if (Visited.insert(Op0).second) +DFT.push_back(Op0); + continue; } @@ -4147,7 +4150,7 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI, if (UsedICmps <= 1) return false; - bool TrueWhenEqual = (Cond->getOpcode() == Instruction::Or); + bool TrueWhenEqual = match(Cond, m_LogicalOr(m_Value(), m_Value())); // There might be duplicate constants in the list, which the switch // instruction can't handle, remove them now. diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll index a4c84a66cafb..3a047313b44a 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll @@ -33,10 +33,10 @@ F: ; preds = %0 define void @test1_select(i32 %V) { ; CHECK-LABEL: @test1_select( -; CHECK-NEXT:[[C1:%.*]] = icmp eq i32 [[V:%.*]], 4 -; CHECK-NEXT:[[C2:%.*]] = icmp eq i32 [[V]], 17 -; CHECK-NEXT:[[CN:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] -; CHECK-NEXT:br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT:switch i32 [[V:%.*]], label [[F:%.*]] [ +; CHECK-NEXT:i32 17, label [[T:%.*]] +; CHECK-NEXT:i32 4, label [[T]] +; CHECK-NEXT:] ; CHECK: T: ; CHECK-NEXT:call void @foo1() ; CHECK-NEXT:ret void @@ -135,10 +135,10 @@ F: ; preds = %0 define void @test2_select(i32 %V) { ; CHECK-LABEL: @test2_select( -; CHECK-NEXT:[[C1:%.*]] = icmp ne i32 [[V:%.*]], 4 -; CHECK-NEXT:[[C2:%.*]] = icmp ne i32 [[V]], 17 -; CHECK-NEXT:[[CN:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false -; CHECK-NEXT:br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK-NEXT:switch i32 [[V:%.*]], label [[T:%.*]] [ +; CHECK-NEXT:i32 17, label [[F:%.*]] +; CHECK-NEXT:i32 4, label [[F]] +; CHECK-NEXT:] ; CHECK: T: ; CHECK-NEXT:call void @foo1() ; CHECK-NEXT:ret void @@ -465,13 +465,17 @@ F: define i32 @test10_select(i32 %mode, i1 %Cond) { ; CHECK-LABEL: @test10_select( -; CHECK-NEXT: T: -; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 -; CHECK-NEXT:[[B:%.*]] = icmp ne i32 [[MODE]], 51 -; CHECK-NEXT:[[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false -; CHECK-NEXT:[[D:%.*]] = select i1 [[C]], i1 [[COND:%.*]], i1 false -; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 -; CHECK-NEXT:ret i32 [[SPEC_SELECT]] +; CHECK-NEXT:br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]] +; CHECK: switch.early.test: +; CHECK-NEXT:switch i32 [[MODE:%.*]], label [[T:%.*]] [ +; CHECK-NEXT:i32 51, label [[F]] +; CHECK-NEXT:
[llvm-branch-commits] [llvm] 0441df9 - [InstCombine, InstSimplify] Optimize select followed by and/or/xor
Author: Juneyoung Lee Date: 2021-01-19T09:14:17+09:00 New Revision: 0441df94ad874c0c59a3785bd54a3d2f9a616fac URL: https://github.com/llvm/llvm-project/commit/0441df94ad874c0c59a3785bd54a3d2f9a616fac DIFF: https://github.com/llvm/llvm-project/commit/0441df94ad874c0c59a3785bd54a3d2f9a616fac.diff LOG: [InstCombine,InstSimplify] Optimize select followed by and/or/xor This patch adds `A & (A && B)` -> `A && B` (similarly for or + logical or) Also, this patch adds `~(select C, (icmp pred X, Y), const)` -> `select C, (icmp pred' X, Y), ~const`. Alive2 proof: merge_and: https://alive2.llvm.org/ce/z/teMR97 merge_or: https://alive2.llvm.org/ce/z/b4yZUp xor_and: https://alive2.llvm.org/ce/z/_-TXHi xor_or: https://alive2.llvm.org/ce/z/2uYx_a Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D94861 Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/test/Transforms/InstCombine/select-safe-transforms.ll Removed: diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 3cab06079a87..c40e5c36cdc7 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2127,12 +2127,21 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, Instruction::Xor, Q, MaxRecurse)) return V; - // If the operation is with the result of a select instruction, check whether - // operating on either branch of the select always yields the same value. - if (isa(Op0) || isa(Op1)) + if (isa(Op0) || isa(Op1)) { +if (Op0->getType()->isIntOrIntVectorTy(1)) { + // A & (A && B) -> A && B + if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero( +return Op1; + else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero( +return Op0; +} +// If the operation is with the result of a select instruction, check +// whether operating on either branch of the select always yields the same +// value. if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, Q, MaxRecurse)) return V; + } // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. @@ -2303,12 +2312,21 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, Instruction::And, Q, MaxRecurse)) return V; - // If the operation is with the result of a select instruction, check whether - // operating on either branch of the select always yields the same value. - if (isa(Op0) || isa(Op1)) + if (isa(Op0) || isa(Op1)) { +if (Op0->getType()->isIntOrIntVectorTy(1)) { + // A | (A || B) -> A || B + if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value( +return Op1; + else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value( +return Op0; +} +// If the operation is with the result of a select instruction, check +// whether operating on either branch of the select always yields the same +// value. if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, Q, MaxRecurse)) return V; + } // (A & C1)|(B & C2) const APInt *C1, *C2; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 352126fa07ca..59291617d2b0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3444,19 +3444,32 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) { } } -// Pull 'not' into operands of select if both operands are one-use compares. +// Pull 'not' into operands of select if both operands are one-use compares +// or one is one-use compare and the other one is a constant. // Inverting the predicates eliminates the 'not' operation. // Example: -// not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) --> +// not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) --> // select ?, (cmp InvTPred, ?, ?), (cmp InvFPred, ?, ?) -// TODO: Canonicalize by hoisting 'not' into an arm of the select if only -// 1 select operand is a cmp? +// not (select ?, (cmp TPred, ?, ?), true --> +// select ?, (cmp InvTPred, ?, ?), false if (auto *Sel = dyn_cast(Op0)) { - auto *CmpT = dyn_cast(Sel->getTrueValue()); - auto *CmpF = dyn_cast(Sel->getFalseValue()); - if (CmpT && CmpF && CmpT->hasOneUse() && CmpF->hasOneUse()) { -CmpT->setPredicate(CmpT->getInversePredicate()); -C
[llvm-branch-commits] [llvm] 2d89ebd - Address unused variable warning
Author: Juneyoung Lee Date: 2021-01-19T09:30:16+09:00 New Revision: 2d89ebd5d17b8d8800606880fe02cd867e4a0b90 URL: https://github.com/llvm/llvm-project/commit/2d89ebd5d17b8d8800606880fe02cd867e4a0b90 DIFF: https://github.com/llvm/llvm-project/commit/2d89ebd5d17b8d8800606880fe02cd867e4a0b90.diff LOG: Address unused variable warning Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 59291617d2b0..c42f113feca3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3460,8 +3460,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) { bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa(TV); bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa(FV); if (InvertibleT && InvertibleF) { -Constant *One = cast(Op1); - if (CmpT) CmpT->setPredicate(CmpT->getInversePredicate()); else ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 4479c0c - Allow nonnull/align attribute to accept poison
Author: Juneyoung Lee Date: 2021-01-20T11:31:23+09:00 New Revision: 4479c0c2c0be019b9932c6f1380a40e6cb48da25 URL: https://github.com/llvm/llvm-project/commit/4479c0c2c0be019b9932c6f1380a40e6cb48da25 DIFF: https://github.com/llvm/llvm-project/commit/4479c0c2c0be019b9932c6f1380a40e6cb48da25.diff LOG: Allow nonnull/align attribute to accept poison Currently LLVM is relying on ValueTracking's `isKnownNonZero` to attach `nonnull`, which can return true when the value is poison. To make the semantics of `nonnull` consistent with the behavior of `isKnownNonZero`, this makes the semantics of `nonnull` to accept poison, and return poison if the input pointer isn't null. This makes many transformations like below legal: ``` %p = gep inbounds %x, 1 ; % p is non-null pointer or poison call void @f(%p); instcombine converts this to call void @f(nonnull %p) ``` Instead, this semantics makes propagation of `nonnull` to caller illegal. The reason is that, passing poison to `nonnull` does not immediately raise UB anymore, so such program is still well defined, if the callee does not use the argument. Having `noundef` attribute there re-allows this. ``` define void @f(i8* %p) { ; functionattr cannot mark %p nonnull here anymore call void @g(i8* nonnull %p) ; .. because @g never raises UB if it never uses %p. ret void } ``` Another attribute that needs to be updated is `align`. This patch updates the semantics of align to accept poison as well. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D90529 Added: Modified: llvm/docs/LangRef.rst llvm/include/llvm/IR/Argument.h llvm/lib/Analysis/ValueTracking.cpp llvm/lib/IR/Function.cpp llvm/lib/Transforms/IPO/FunctionAttrs.cpp llvm/test/Analysis/ValueTracking/known-nonnull-at.ll llvm/test/Transforms/Attributor/align.ll llvm/test/Transforms/Attributor/nonnull.ll llvm/test/Transforms/FunctionAttrs/nonnull.ll llvm/test/Transforms/InstCombine/call_nonnull_arg.ll llvm/test/Transforms/InstCombine/unused-nonnull.ll Removed: diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 1b6052f58f9d..cd3bb0de4f34 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1160,10 +1160,12 @@ Currently, only the following parameter attributes are defined: .. _attr_align: ``align `` or ``align()`` -This indicates that the pointer value may be assumed by the optimizer to -have the specified alignment. If the pointer value does not have the -specified alignment, behavior is undefined. ``align 1`` has no effect on -non-byval, non-preallocated arguments. +This indicates that the pointer value has the specified alignment. +If the pointer value does not have the specified alignment, +:ref:`poison value ` is returned or passed instead. The +``align`` attribute should be combined with the ``noundef`` attribute to +ensure a pointer is aligned, or otherwise the behavior is undefined. Note +that ``align 1`` has no effect on non-byval, non-preallocated arguments. Note that this attribute has additional semantics when combined with the ``byval`` or ``preallocated`` attribute, which are documented there. @@ -1225,7 +1227,9 @@ Currently, only the following parameter attributes are defined: This indicates that the parameter or return pointer is not null. This attribute may only be applied to pointer typed parameters. This is not checked or enforced by LLVM; if the parameter or return pointer is null, -the behavior is undefined. +:ref:`poison value ` is returned or passed instead. +The ``nonnull`` attribute should be combined with the ``noundef`` attribute +to ensure a pointer is not null or otherwise the behavior is undefined. ``dereferenceable()`` This indicates that the parameter or return pointer is dereferenceable. This diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h index f59a498dc75d..76d780485ea0 100644 --- a/llvm/include/llvm/IR/Argument.h +++ b/llvm/include/llvm/IR/Argument.h @@ -52,7 +52,9 @@ class Argument final : public Value { /// Return true if this argument has the nonnull attribute. Also returns true /// if at least one byte is known to be dereferenceable and the pointer is in /// addrspace(0). - bool hasNonNullAttr() const; + /// If AllowUndefOrPoison is true, respect the semantics of nonnull attribute + /// and return true even if the argument can be undef or poison. + bool hasNonNullAttr(bool AllowUndefOrPoison = true) const; /// If this argument has the dereferenceable attribute, return the number of /// bytes known to be dereferenceable. Otherwise, zero is returned. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 4f0c7057089b..ef3558ef136e 100644 --- a/llvm/lib/Analysis/ValueTrack
[llvm-branch-commits] [llvm] 2e74a27 - [SimplifyCFG] Reapply update_test_checks.py (NFC)
Author: Juneyoung Lee Date: 2021-01-20T12:41:30+09:00 New Revision: 2e74a2775665eea221c6819af44011f7489df856 URL: https://github.com/llvm/llvm-project/commit/2e74a2775665eea221c6819af44011f7489df856 DIFF: https://github.com/llvm/llvm-project/commit/2e74a2775665eea221c6819af44011f7489df856.diff LOG: [SimplifyCFG] Reapply update_test_checks.py (NFC) Added: Modified: llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll Removed: diff --git a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll index 078d0aa2f1de..25106d435cc7 100644 --- a/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll +++ b/llvm/test/Transforms/SimplifyCFG/preserve-branchweights.ll @@ -318,10 +318,10 @@ define void @test8(i64 %x, i64 %y) nounwind { ; CHECK-NEXT:[[LT:%.*]] = icmp slt i64 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT:br i1 [[LT]], label [[A:%.*]], label [[B:%.*]], !prof !7 ; CHECK: a: -; CHECK-NEXT:call void @helper(i32 0) #1 +; CHECK-NEXT:call void @helper(i32 0) [[ATTR1:#.*]] ; CHECK-NEXT:ret void ; CHECK: b: -; CHECK-NEXT:call void @helper(i32 1) #1 +; CHECK-NEXT:call void @helper(i32 1) [[ATTR1]] ; CHECK-NEXT:ret void ; entry: @@ -355,14 +355,14 @@ define i1 @test9(i32 %x, i32 %y) nounwind { ; CHECK-NEXT:i32 92, label [[END]] ; CHECK-NEXT:], !prof !8 ; CHECK: a: -; CHECK-NEXT:call void @helper(i32 0) #1 +; CHECK-NEXT:call void @helper(i32 0) [[ATTR1]] ; CHECK-NEXT:[[RETA:%.*]] = icmp slt i32 [[X]], [[Y:%.*]] ; CHECK-NEXT:ret i1 [[RETA]] ; CHECK: bees: ; CHECK-NEXT:br label [[END]] ; CHECK: end: ; CHECK-NEXT:[[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[BEES]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ] -; CHECK-NEXT:call void @helper(i32 2) #1 +; CHECK-NEXT:call void @helper(i32 2) [[ATTR1]] ; CHECK-NEXT:ret i1 [[RET]] ; entry: @@ -394,10 +394,10 @@ define void @test10(i32 %x) nounwind readnone ssp noredzone { ; CHECK-NEXT:[[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 ; CHECK-NEXT:br i1 [[SWITCH]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]], !prof !9 ; CHECK: lor.rhs: -; CHECK-NEXT:call void @helper(i32 1) #1 +; CHECK-NEXT:call void @helper(i32 1) [[ATTR1]] ; CHECK-NEXT:ret void ; CHECK: lor.end: -; CHECK-NEXT:call void @helper(i32 0) #1 +; CHECK-NEXT:call void @helper(i32 0) [[ATTR1]] ; CHECK-NEXT:ret void ; entry: @@ -424,10 +424,10 @@ define void @test11(i32 %x) nounwind { ; CHECK-NEXT:[[COND:%.*]] = icmp eq i32 [[I]], 24 ; CHECK-NEXT:br i1 [[COND]], label [[C:%.*]], label [[A:%.*]], !prof !10 ; CHECK: a: -; CHECK-NEXT:call void @helper(i32 0) #1 +; CHECK-NEXT:call void @helper(i32 0) [[ATTR1]] ; CHECK-NEXT:ret void ; CHECK: c: -; CHECK-NEXT:call void @helper(i32 2) #1 +; CHECK-NEXT:call void @helper(i32 2) [[ATTR1]] ; CHECK-NEXT:ret void ; %i = shl i32 %x, 1 @@ -472,7 +472,7 @@ sw.epilog: define void @test13(i32 %x) nounwind { ; CHECK-LABEL: @test13( ; CHECK-NEXT: entry: -; CHECK-NEXT:call void @helper(i32 0) #1 +; CHECK-NEXT:call void @helper(i32 0) [[ATTR1]] ; CHECK-NEXT:ret void ; entry: @@ -541,8 +541,8 @@ define i32 @HoistThenElseCodeToIf(i32 %n) { ; CHECK-LABEL: @HoistThenElseCodeToIf( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[TOBOOL:%.*]] = icmp eq i32 [[N:%.*]], 0 -; CHECK-NEXT:[[DOT:%.*]] = select i1 [[TOBOOL]], i32 1, i32 234, !prof !12 -; CHECK-NEXT:ret i32 [[DOT]] +; CHECK-NEXT:[[RETVAL_0:%.*]] = select i1 [[TOBOOL]], i32 1, i32 234, !prof !12 +; CHECK-NEXT:ret i32 [[RETVAL_0]] ; entry: %tobool = icmp eq i32 %n, 0 diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll index cdc334e474b6..a4f9e1dd29dd 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_create-custom-dl.ll @@ -208,7 +208,7 @@ define i1 @test6({ i32, i32 }* %I) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1 -; CHECK-NEXT:[[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]] +; CHECK-NEXT:[[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]], align 4 ; CHECK-NEXT:[[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14 ; CHECK-NEXT:[[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6 ; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false @@ -253,7 +253,7 @@ define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { ; CHECK-NEXT:i8 97, label [[IF_THEN]] ; CHECK-NEXT:] ; CHECK: if.then: -; CHECK-NEXT:tail call void @foo1() #2 +; CHEC
[llvm-branch-commits] [llvm] 0f2c180 - [ValueTracking] Implement impliesPoison
Author: Juneyoung Lee Date: 2020-12-29T06:50:38+09:00 New Revision: 0f2c180163a2cc3d6239a32d379ec3d773e56a2f URL: https://github.com/llvm/llvm-project/commit/0f2c180163a2cc3d6239a32d379ec3d773e56a2f DIFF: https://github.com/llvm/llvm-project/commit/0f2c180163a2cc3d6239a32d379ec3d773e56a2f.diff LOG: [ValueTracking] Implement impliesPoison This PR adds impliesPoison(ValAssumedPoison, V) that returns true if V is poison under the assumption that ValAssumedPoison is poison. For example, impliesPoison('icmp X, 10', 'icmp X, Y') return true because 'icmp X, Y' is poison if 'icmp X, 10' is poison. impliesPoison can be used for sound optimization of select, as discussed in D77868. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D78152 Added: Modified: llvm/include/llvm/Analysis/ValueTracking.h llvm/lib/Analysis/ValueTracking.cpp llvm/unittests/Analysis/ValueTrackingTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index f8ca8b8015bf..86c0991451c5 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -620,6 +620,11 @@ constexpr unsigned MaxAnalysisRecursionDepth = 6; bool canCreateUndefOrPoison(const Operator *Op); bool canCreatePoison(const Operator *Op); + /// Return true if V is poison given that ValAssumedPoison is already poison. + /// For example, if ValAssumedPoison is `icmp X, 10` and V is `icmp X, 5`, + /// impliesPoison returns true. + bool impliesPoison(const Value *ValAssumedPoison, const Value *V); + /// Return true if this function can prove that V does not have undef bits /// and is never poison. If V is an aggregate value or vector, check whether /// all elements (except padding) are not undef or poison. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0e32e7f4b102..303240d03c72 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4809,6 +4809,64 @@ bool llvm::canCreatePoison(const Operator *Op) { return ::canCreateUndefOrPoison(Op, /*PoisonOnly=*/true); } +bool llvm::impliesPoison(const Value *ValAssumedPoison, const Value *V) { + // Construct a set of values which are known to be poison from the knowledge + // that ValAssumedPoison is poison. + SmallPtrSet PoisonValues; + PoisonValues.insert(ValAssumedPoison); + const Instruction *PoisonI = dyn_cast(ValAssumedPoison); + unsigned Depth = 0; + const unsigned MaxDepth = 2; + + while (PoisonI && Depth < MaxDepth) { +// We'd like to know whether an operand of PoisonI is also poison. +if (canCreatePoison(cast(PoisonI))) + // PoisonI can be a poison-generating instruction, so don't look further + break; + +const Value *NextVal = nullptr; +bool MoreThanOneCandidate = false; +// See which operand can be poison +for (const auto &Op : PoisonI->operands()) { + if (!isGuaranteedNotToBeUndefOrPoison(Op.get())) { +// Op can be poison. +if (NextVal) { + // There is more than one operand that can make PoisonI poison. + MoreThanOneCandidate = true; + break; +} +NextVal = Op.get(); + } +} + +if (NextVal == nullptr) { + // All operands are non-poison, so PoisonI cannot be poison. + // Since assumption is false, return true + return true; +} else if (MoreThanOneCandidate) + break; + +Depth++; +PoisonValues.insert(NextVal); +PoisonI = dyn_cast(NextVal); + } + + if (PoisonValues.contains(V)) +return true; + + // Let's look one level further, by seeing its arguments if I was an + // instruction. + // This happens when I is e.g. 'icmp X, const' where X is in PoisonValues. + const auto *I = dyn_cast(V); + if (I && propagatesPoison(cast(I))) { +for (const auto &Op : I->operands()) + if (PoisonValues.count(Op.get())) +return true; + } + + return false; +} + static bool programUndefinedIfUndefOrPoison(const Value *V, bool PoisonOnly); diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 8d24f524b59d..009166a24a1f 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -695,6 +695,59 @@ TEST_F(ValueTrackingTest, ComputeNumSignBits_Shuffle2) { EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u); } +TEST_F(ValueTrackingTest, impliesPoisonTest_Identity) { + parseAssembly("define void @test(i32 %x, i32 %y) {\n" +" %A = add i32 %x, %y\n" +" ret void\n" +"}"); + EXPECT_TRUE(impliesPoison(A, A)); +} + +TEST_F(ValueTrackingTest, impliesPoisonTest_ICmp) { + parseAssembly("define void @test(i32 %x) {\n"
[llvm-branch-commits] [llvm] 8b67c98 - [UpdateTestChecks] Fix update_analyze_test_checks.py failure
Author: Juneyoung Lee Date: 2020-12-29T11:56:59+09:00 New Revision: 8b67c98c4774313ab0ce5db1a975d2e69850368a URL: https://github.com/llvm/llvm-project/commit/8b67c98c4774313ab0ce5db1a975d2e69850368a DIFF: https://github.com/llvm/llvm-project/commit/8b67c98c4774313ab0ce5db1a975d2e69850368a.diff LOG: [UpdateTestChecks] Fix update_analyze_test_checks.py failure Added: Modified: llvm/utils/update_analyze_test_checks.py Removed: diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py index 38add9d4ab01..921a3bc08537 100755 --- a/llvm/utils/update_analyze_test_checks.py +++ b/llvm/utils/update_analyze_test_checks.py @@ -110,7 +110,10 @@ def main(): builder = common.FunctionTestBuilder( run_list = prefix_list, - flags = args, + flags = type('', (object,), { +'verbose': args.verbose, +'function_signature': False, +'check_attributes': False}), scrubber_args = []) for prefixes, opt_args in prefix_list: ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 109e073 - [ConstraintElimination] Add tests for select form and/or (NFC)
Author: Juneyoung Lee Date: 2020-12-30T16:05:19+09:00 New Revision: 109e0736620cc3ca618e80ec3c1f2f267ee2e026 URL: https://github.com/llvm/llvm-project/commit/109e0736620cc3ca618e80ec3c1f2f267ee2e026 DIFF: https://github.com/llvm/llvm-project/commit/109e0736620cc3ca618e80ec3c1f2f267ee2e026.diff LOG: [ConstraintElimination] Add tests for select form and/or (NFC) Added: Modified: llvm/test/Transforms/ConstraintElimination/and.ll llvm/test/Transforms/ConstraintElimination/or.ll Removed: diff --git a/llvm/test/Transforms/ConstraintElimination/and.ll b/llvm/test/Transforms/ConstraintElimination/and.ll index d8962b39ebd5..c9b633049757 100644 --- a/llvm/test/Transforms/ConstraintElimination/and.ll +++ b/llvm/test/Transforms/ConstraintElimination/and.ll @@ -48,6 +48,72 @@ bb1: call void @use(i1 %t.3) + %c.3 = icmp ule i32 %x, %a + call void @use(i1 %c.3) + + ret i32 10 + +exit: + %c.4 = icmp ule i32 %x, %z + call void @use(i1 %c.4) + + %c.5 = icmp ule i32 %x, %a + call void @use(i1 %c.5) + + %c.6 = icmp ule i32 %x, %y + call void @use(i1 %c.6) + + %c.7 = icmp ule i32 %y, %z + call void @use(i1 %c.7) + + ret i32 20 +} + +define i32 @test_and_select_ule(i32 %x, i32 %y, i32 %z, i32 %a) { +; CHECK-LABEL: @test_and_select_ule( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[C_1:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[C_2:%.*]] = icmp ule i32 [[Y]], [[Z:%.*]] +; CHECK-NEXT:[[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false +; CHECK-NEXT:br i1 [[AND]], label [[BB1:%.*]], label [[EXIT:%.*]] +; CHECK: bb1: +; CHECK-NEXT:[[T_1:%.*]] = icmp ule i32 [[X]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[T_1]]) +; CHECK-NEXT:[[T_2:%.*]] = icmp ule i32 [[X]], [[Y]] +; CHECK-NEXT:call void @use(i1 [[T_2]]) +; CHECK-NEXT:[[T_3:%.*]] = icmp ule i32 [[Y]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[T_3]]) +; CHECK-NEXT:[[C_3:%.*]] = icmp ule i32 [[X]], [[A:%.*]] +; CHECK-NEXT:call void @use(i1 [[C_3]]) +; CHECK-NEXT:ret i32 10 +; CHECK: exit: +; CHECK-NEXT:[[C_4:%.*]] = icmp ule i32 [[X]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[C_4]]) +; CHECK-NEXT:[[C_5:%.*]] = icmp ule i32 [[X]], [[A]] +; CHECK-NEXT:call void @use(i1 [[C_5]]) +; CHECK-NEXT:[[C_6:%.*]] = icmp ule i32 [[X]], [[Y]] +; CHECK-NEXT:call void @use(i1 [[C_6]]) +; CHECK-NEXT:[[C_7:%.*]] = icmp ule i32 [[Y]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[C_7]]) +; CHECK-NEXT:ret i32 20 +; +entry: + %c.1 = icmp ule i32 %x, %y + %c.2 = icmp ule i32 %y, %z + %and = select i1 %c.1, i1 %c.2, i1 false + br i1 %and, label %bb1, label %exit + +bb1: + %t.1 = icmp ule i32 %x, %z + call void @use(i1 %t.1) + + %t.2 = icmp ule i32 %x, %y + call void @use(i1 %t.2) + + %t.3 = icmp ule i32 %y, %z + call void @use(i1 %t.3) + + %c.3 = icmp ule i32 %x, %a call void @use(i1 %c.3) diff --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Transforms/ConstraintElimination/or.ll index 31a1803d8621..b97887043eb9 100644 --- a/llvm/test/Transforms/ConstraintElimination/or.ll +++ b/llvm/test/Transforms/ConstraintElimination/or.ll @@ -62,3 +62,63 @@ exit: ret i32 20 } + +define i32 @test_or_select_ule(i32 %x, i32 %y, i32 %z, i32 %a) { +; CHECK-LABEL: @test_or_select_ule( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[C_1:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[C_2:%.*]] = icmp ule i32 [[Y]], [[Z:%.*]] +; CHECK-NEXT:[[OR:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]] +; CHECK-NEXT:br i1 [[OR]], label [[BB1:%.*]], label [[EXIT:%.*]] +; CHECK: bb1: +; CHECK-NEXT:[[C_3:%.*]] = icmp ule i32 [[X]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[C_3]]) +; CHECK-NEXT:[[C_4:%.*]] = icmp ule i32 [[X]], [[A:%.*]] +; CHECK-NEXT:call void @use(i1 [[C_4]]) +; CHECK-NEXT:ret i32 10 +; CHECK: exit: +; CHECK-NEXT:[[F_1:%.*]] = icmp ule i32 [[X]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[F_1]]) +; CHECK-NEXT:[[C_5:%.*]] = icmp ule i32 [[X]], [[A]] +; CHECK-NEXT:call void @use(i1 [[C_5]]) +; CHECK-NEXT:[[T_1:%.*]] = icmp ugt i32 [[Y]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[T_1]]) +; CHECK-NEXT:[[T_2:%.*]] = icmp ugt i32 [[X]], [[Y]] +; CHECK-NEXT:call void @use(i1 [[T_2]]) +; CHECK-NEXT:[[T_3:%.*]] = icmp ugt i32 [[X]], [[Z]] +; CHECK-NEXT:call void @use(i1 [[T_3]]) +; CHECK-NEXT:ret i32 20 +; +entry: + %c.1 = icmp ule i32 %x, %y + %c.2 = icmp ule i32 %y, %z + %or = select i1 %c.1, i1 true, i1 %c.2 + br i1 %or, label %bb1, label %exit + +bb1: + %c.3 = icmp ule i32 %x, %z + call void @use(i1 %c.3) + + %c.4 = icmp ule i32 %x, %a + call void @use(i1 %c.4) + + ret i32 10 + +exit: + %f.1 = icmp ule i32 %x, %z + call void @use(i1 %f.1) + + %c.5 = icmp ule i32 %x, %a + call void @use(i1 %c.5) + + %t.1 = icmp ugt i32 %y, %z + call void @use(i1 %t.1) + +
[llvm-branch-commits] [llvm] bfedd5d - [ConstraintElimination] Add support for select form of and/or
Author: Juneyoung Lee Date: 2020-12-30T21:27:36+09:00 New Revision: bfedd5d2b650e0fcef9c16907e8b694d9b213181 URL: https://github.com/llvm/llvm-project/commit/bfedd5d2b650e0fcef9c16907e8b694d9b213181 DIFF: https://github.com/llvm/llvm-project/commit/bfedd5d2b650e0fcef9c16907e8b694d9b213181.diff LOG: [ConstraintElimination] Add support for select form of and/or This patch adds support for select form of and/or. Currently there is an ongoing effort for moving towards using `select a, b, false` instead of `and i1 a, b` and `select a, true, b` instead of `or i1 a, b` as well. D93065 has links to relevant changes. Alive2 proof: (undef input was disabled due to timeout :( ) - and: https://alive2.llvm.org/ce/z/AgvFbQ - or: https://alive2.llvm.org/ce/z/KjLJyb Differential Revision: https://reviews.llvm.org/D93935 Added: Modified: llvm/lib/Transforms/Scalar/ConstraintElimination.cpp llvm/test/Transforms/ConstraintElimination/and.ll llvm/test/Transforms/ConstraintElimination/or.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 616518cbcfdc..35c6c415341a 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -218,14 +218,15 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) { // If the condition is an OR of 2 compares and the false successor only has // the current block as predecessor, queue both negated conditions for the // false successor. -if (match(Br->getCondition(), m_Or(m_Cmp(), m_Cmp( { +Value *Op0, *Op1; +if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) && +match(Op0, m_Cmp()) && match(Op1, m_Cmp())) { BasicBlock *FalseSuccessor = Br->getSuccessor(1); if (FalseSuccessor->getSinglePredecessor()) { -auto *OrI = cast(Br->getCondition()); -WorkList.emplace_back(DT.getNode(FalseSuccessor), - cast(OrI->getOperand(0)), true); -WorkList.emplace_back(DT.getNode(FalseSuccessor), - cast(OrI->getOperand(1)), true); +WorkList.emplace_back(DT.getNode(FalseSuccessor), cast(Op0), + true); +WorkList.emplace_back(DT.getNode(FalseSuccessor), cast(Op1), + true); } continue; } @@ -233,14 +234,14 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) { // If the condition is an AND of 2 compares and the true successor only has // the current block as predecessor, queue both conditions for the true // successor. -if (match(Br->getCondition(), m_And(m_Cmp(), m_Cmp( { +if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) && +match(Op0, m_Cmp()) && match(Op1, m_Cmp())) { BasicBlock *TrueSuccessor = Br->getSuccessor(0); if (TrueSuccessor->getSinglePredecessor()) { -auto *AndI = cast(Br->getCondition()); -WorkList.emplace_back(DT.getNode(TrueSuccessor), - cast(AndI->getOperand(0)), false); -WorkList.emplace_back(DT.getNode(TrueSuccessor), - cast(AndI->getOperand(1)), false); +WorkList.emplace_back(DT.getNode(TrueSuccessor), cast(Op0), + false); +WorkList.emplace_back(DT.getNode(TrueSuccessor), cast(Op1), + false); } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/and.ll b/llvm/test/Transforms/ConstraintElimination/and.ll index c9b633049757..e1ec8490a792 100644 --- a/llvm/test/Transforms/ConstraintElimination/and.ll +++ b/llvm/test/Transforms/ConstraintElimination/and.ll @@ -69,6 +69,7 @@ exit: ret i32 20 } +; The result of test_and_ule and test_and_select_ule should be same define i32 @test_and_select_ule(i32 %x, i32 %y, i32 %z, i32 %a) { ; CHECK-LABEL: @test_and_select_ule( ; CHECK-NEXT: entry: @@ -78,11 +79,11 @@ define i32 @test_and_select_ule(i32 %x, i32 %y, i32 %z, i32 %a) { ; CHECK-NEXT:br i1 [[AND]], label [[BB1:%.*]], label [[EXIT:%.*]] ; CHECK: bb1: ; CHECK-NEXT:[[T_1:%.*]] = icmp ule i32 [[X]], [[Z]] -; CHECK-NEXT:call void @use(i1 [[T_1]]) +; CHECK-NEXT:call void @use(i1 true) ; CHECK-NEXT:[[T_2:%.*]] = icmp ule i32 [[X]], [[Y]] -; CHECK-NEXT:call void @use(i1 [[T_2]]) +; CHECK-NEXT:call void @use(i1 true) ; CHECK-NEXT:[[T_3:%.*]] = icmp ule i32 [[Y]], [[Z]] -; CHECK-NEXT:call void @use(i1 [[T_3]]) +; CHECK-NEXT:call void @use(i1 true) ; CHECK-NEXT:[[C_3:%.*]] = icmp ule i32 [[X]], [[A:%.*]] ; CHECK-NEXT:call void @use(i1 [[C_3]]) ; CHECK-NEXT:ret i32 10 diff --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Tr
[llvm-branch-commits] [llvm] e6e6404 - [SimplifyCFG] Add tests for select form and/or for creating select from icmps
Author: Juneyoung Lee Date: 2020-12-30T22:15:39+09:00 New Revision: e6e6404600281d4ae34162a5853e7a9cdbe50d44 URL: https://github.com/llvm/llvm-project/commit/e6e6404600281d4ae34162a5853e7a9cdbe50d44 DIFF: https://github.com/llvm/llvm-project/commit/e6e6404600281d4ae34162a5853e7a9cdbe50d44.diff LOG: [SimplifyCFG] Add tests for select form and/or for creating select from icmps Added: Modified: llvm/test/Transforms/SimplifyCFG/switch_create.ll Removed: diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll index 3314fc982ae7..cc7a48904482 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll @@ -31,6 +31,31 @@ F: ; preds = %0 ret void } +define void @test1_select(i32 %V) { +; CHECK-LABEL: @test1_select( +; CHECK-NEXT:[[C1:%.*]] = icmp eq i32 [[V:%.*]], 4 +; CHECK-NEXT:[[C2:%.*]] = icmp eq i32 [[V]], 17 +; CHECK-NEXT:[[CN:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] +; CHECK-NEXT:br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT:call void @foo1() +; CHECK-NEXT:ret void +; CHECK: F: +; CHECK-NEXT:call void @foo2() +; CHECK-NEXT:ret void +; + %C1 = icmp eq i32 %V, 4 + %C2 = icmp eq i32 %V, 17 + %CN = select i1 %C1, i1 true, i1 %C2 + br i1 %CN, label %T, label %F +T: + call void @foo1( ) + ret void +F: + call void @foo2( ) + ret void +} + define void @test1_ptr(i32* %V) { ; DL-LABEL: @test1_ptr( ; DL-NEXT:[[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i32 @@ -108,6 +133,31 @@ F: ; preds = %0 ret void } +define void @test2_select(i32 %V) { +; CHECK-LABEL: @test2_select( +; CHECK-NEXT:[[C1:%.*]] = icmp ne i32 [[V:%.*]], 4 +; CHECK-NEXT:[[C2:%.*]] = icmp ne i32 [[V]], 17 +; CHECK-NEXT:[[CN:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false +; CHECK-NEXT:br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT:call void @foo1() +; CHECK-NEXT:ret void +; CHECK: F: +; CHECK-NEXT:call void @foo2() +; CHECK-NEXT:ret void +; + %C1 = icmp ne i32 %V, 4 + %C2 = icmp ne i32 %V, 17 + %CN = select i1 %C1, i1 %C2, i1 false + br i1 %CN, label %T, label %F +T: + call void @foo1( ) + ret void +F: + call void @foo2( ) + ret void +} + define void @test3(i32 %V) { ; CHECK-LABEL: @test3( ; CHECK-NEXT:switch i32 [[V:%.*]], label [[F:%.*]] [ @@ -208,7 +258,7 @@ define i1 @test6({ i32, i32 }* %I) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1 -; CHECK-NEXT:[[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]] +; CHECK-NEXT:[[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]], align 4 ; CHECK-NEXT:[[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14 ; CHECK-NEXT:[[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6 ; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false @@ -253,7 +303,7 @@ define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { ; CHECK-NEXT:i8 97, label [[IF_THEN]] ; CHECK-NEXT:] ; CHECK: if.then: -; CHECK-NEXT:tail call void @foo1() #2 +; CHECK-NEXT:tail call void @foo1() [[ATTR2:#.*]] ; CHECK-NEXT:ret void ; CHECK: if.end: ; CHECK-NEXT:ret void @@ -289,7 +339,7 @@ define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { ; CHECK-NEXT:] ; CHECK: if.then: ; CHECK-NEXT:[[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ] -; CHECK-NEXT:tail call void @foo1() #2 +; CHECK-NEXT:tail call void @foo1() [[ATTR2]] ; CHECK-NEXT:ret i32 [[A]] ; CHECK: if.end: ; CHECK-NEXT:ret i32 0 @@ -413,6 +463,28 @@ F: } +define i32 @test10_select(i32 %mode, i1 %Cond) { +; CHECK-LABEL: @test10_select( +; CHECK-NEXT: T: +; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 +; CHECK-NEXT:[[B:%.*]] = icmp ne i32 [[MODE]], 51 +; CHECK-NEXT:[[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false +; CHECK-NEXT:[[D:%.*]] = and i1 [[C]], [[COND:%.*]] +; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 +; CHECK-NEXT:ret i32 [[SPEC_SELECT]] +; + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = select i1 %A, i1 %B, i1 false + %D = and i1 %C, %Cond + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +} + ; PR8780 define i32 @test11(i32 %bar) nounwind { ; CHECK-LABEL: @test11( @@ -465,8 +537,8 @@ return: ; preds = %if.end, %if.then define void @test12() nounwind { ; CHECK-LABEL: @test12( ; CHECK-NEXT: entry: -; CHECK-NEXT:[[A_OLD:%.*]] = icmp eq i32 undef, undef -; CHECK-NEXT:br i1 [[A_OLD]], label [[BB55_US_US:%.*]],
[llvm-branch-commits] [llvm] 420d046 - clang-format, address warnings
Author: Juneyoung Lee Date: 2020-12-30T23:05:07+09:00 New Revision: 420d046d6bdd8d950dad389a97e31f841052efb2 URL: https://github.com/llvm/llvm-project/commit/420d046d6bdd8d950dad389a97e31f841052efb2 DIFF: https://github.com/llvm/llvm-project/commit/420d046d6bdd8d950dad389a97e31f841052efb2.diff LOG: clang-format, address warnings Added: Modified: clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c clang/test/CodeGen/X86/avx512f-builtins.c clang/test/CodeGen/X86/avx512vl-builtins-constrained.c clang/test/CodeGen/arm64-abi-vector.c llvm/lib/IR/AutoUpgrade.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp Removed: diff --git a/clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c b/clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c index bb43d348205f..d32eb4b00040 100644 --- a/clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c +++ b/clang/test/CodeGen/X86/avx512-reduceMinMaxIntrin.c @@ -15,16 +15,16 @@ unsigned long long test_mm512_reduce_max_epu64(__m512i __W){ } double test_mm512_reduce_max_pd(__m512d __W){ -// CHECK-LABEL: @test_mm512_reduce_max_pd( -// CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> -// CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> -// CHECK:call <4 x double> @llvm.x86.avx.max.pd.256(<4 x double> %{{.*}}, <4 x double> %{{.*}}) -// CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> -// CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> -// CHECK:call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) -// CHECK:shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> -// CHECK:call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) -// CHECK:extractelement <2 x double> %{{.*}}, i32 0 + // CHECK-LABEL: @test_mm512_reduce_max_pd( + // CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> + // CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> + // CHECK:call <4 x double> @llvm.x86.avx.max.pd.256(<4 x double> %{{.*}}, <4 x double> %{{.*}}) + // CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> + // CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> + // CHECK:call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK:shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> + // CHECK:call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK:extractelement <2 x double> %{{.*}}, i32 0 return _mm512_reduce_max_pd(__W); } @@ -41,16 +41,16 @@ unsigned long long test_mm512_reduce_min_epu64(__m512i __W){ } double test_mm512_reduce_min_pd(__m512d __W){ -// CHECK-LABEL: @test_mm512_reduce_min_pd( -// CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> -// CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> -// CHECK:call <4 x double> @llvm.x86.avx.min.pd.256(<4 x double> %{{.*}}, <4 x double> %{{.*}}) -// CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> -// CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> -// CHECK:call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) -// CHECK:shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> -// CHECK:call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) -// CHECK:extractelement <2 x double> %{{.*}}, i32 0 + // CHECK-LABEL: @test_mm512_reduce_min_pd( + // CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> + // CHECK:shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> + // CHECK:call <4 x double> @llvm.x86.avx.min.pd.256(<4 x double> %{{.*}}, <4 x double> %{{.*}}) + // CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> + // CHECK:shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> + // CHECK:call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK:shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> + // CHECK:call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK:extractelement <2 x double> %{{.*}}, i32 0 return _mm512_reduce_min_pd(__W); } @@ -71,18 +71,18 @@ unsigned long test_mm512_mask_reduce_max_epu64(__mmask8 __M, __m512i __W){ } double test_mm512_mask_reduce_max_pd(__mmask8 __M, __m512d __W){ -// CHECK-LABEL: @test_mm512_
[llvm-branch-commits] [llvm] c6035a7 - Remove functions from *-inseltpoison.ll tests if unnecessary
Author: Juneyoung Lee Date: 2020-12-30T23:50:37+09:00 New Revision: c6035a7bdf207dc3c1e12c041d5658770893fc68 URL: https://github.com/llvm/llvm-project/commit/c6035a7bdf207dc3c1e12c041d5658770893fc68 DIFF: https://github.com/llvm/llvm-project/commit/c6035a7bdf207dc3c1e12c041d5658770893fc68.diff LOG: Remove functions from *-inseltpoison.ll tests if unnecessary X-inseltpoison.ll is a copy of X.ll with insertelement/shufflevector's placeholder replaced with poison. This commit removes a few redundant functions which do not contain any shufflevector/insertelement. Added: Modified: llvm/test/Transforms/InstCombine/assume-inseltpoison.ll llvm/test/Transforms/InstCombine/bswap-inseltpoison.ll llvm/test/Transforms/InstCombine/fmul-inseltpoison.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/assume-inseltpoison.ll b/llvm/test/Transforms/InstCombine/assume-inseltpoison.ll index 8c04c4af28ced..f49755570ddc9 100644 --- a/llvm/test/Transforms/InstCombine/assume-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/assume-inseltpoison.ll @@ -4,368 +4,10 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" +; A copy of assume.ll, with undef at insertelement/shufflevector replaced with +; poison. declare void @llvm.assume(i1) #1 -; Check that the alignment has been upgraded and that the assume has not -; been removed: - -define i32 @foo1(i32* %a) #0 { -; CHECK-LABEL: @foo1( -; CHECK-NEXT:[[T0:%.*]] = load i32, i32* [[A:%.*]], align 32 -; CHECK-NEXT:[[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 -; CHECK-NEXT:[[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 -; CHECK-NEXT:[[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -; CHECK-NEXT:tail call void @llvm.assume(i1 [[MASKCOND]]) -; CHECK-NEXT:ret i32 [[T0]] -; - %t0 = load i32, i32* %a, align 4 - %ptrint = ptrtoint i32* %a to i64 - %maskedptr = and i64 %ptrint, 31 - %maskcond = icmp eq i64 %maskedptr, 0 - tail call void @llvm.assume(i1 %maskcond) - ret i32 %t0 -} - -; Same check as in @foo1, but make sure it works if the assume is first too. - -define i32 @foo2(i32* %a) #0 { -; CHECK-LABEL: @foo2( -; CHECK-NEXT:[[PTRINT:%.*]] = ptrtoint i32* [[A:%.*]] to i64 -; CHECK-NEXT:[[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 -; CHECK-NEXT:[[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -; CHECK-NEXT:tail call void @llvm.assume(i1 [[MASKCOND]]) -; CHECK-NEXT:[[T0:%.*]] = load i32, i32* [[A]], align 32 -; CHECK-NEXT:ret i32 [[T0]] -; - %ptrint = ptrtoint i32* %a to i64 - %maskedptr = and i64 %ptrint, 31 - %maskcond = icmp eq i64 %maskedptr, 0 - tail call void @llvm.assume(i1 %maskcond) - %t0 = load i32, i32* %a, align 4 - ret i32 %t0 -} - -define i32 @simple(i32 %a) #1 { -; CHECK-LABEL: @simple( -; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[A:%.*]], 4 -; CHECK-NEXT:tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT:ret i32 4 -; - %cmp = icmp eq i32 %a, 4 - tail call void @llvm.assume(i1 %cmp) - ret i32 %a -} - -define i32 @can1(i1 %a, i1 %b, i1 %c) { -; CHECK-LABEL: @can1( -; CHECK-NEXT:call void @llvm.assume(i1 [[A:%.*]]) -; CHECK-NEXT:call void @llvm.assume(i1 [[B:%.*]]) -; CHECK-NEXT:call void @llvm.assume(i1 [[C:%.*]]) -; CHECK-NEXT:ret i32 5 -; - %and1 = and i1 %a, %b - %and = and i1 %and1, %c - tail call void @llvm.assume(i1 %and) - ret i32 5 -} - -define i32 @can2(i1 %a, i1 %b, i1 %c) { -; CHECK-LABEL: @can2( -; CHECK-NEXT:[[TMP1:%.*]] = xor i1 [[A:%.*]], true -; CHECK-NEXT:call void @llvm.assume(i1 [[TMP1]]) -; CHECK-NEXT:[[TMP2:%.*]] = xor i1 [[B:%.*]], true -; CHECK-NEXT:call void @llvm.assume(i1 [[TMP2]]) -; CHECK-NEXT:ret i32 5 -; - %v = or i1 %a, %b - %w = xor i1 %v, 1 - tail call void @llvm.assume(i1 %w) - ret i32 5 -} - -define i32 @bar1(i32 %a) #0 { -; CHECK-LABEL: @bar1( -; CHECK-NEXT:[[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT:tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT:ret i32 1 -; - %and1 = and i32 %a, 3 - %and = and i32 %a, 7 - %cmp = icmp eq i32 %and, 1 - tail call void @llvm.assume(i1 %cmp) - ret i32 %and1 -} - -define i32 @bar2(i32 %a) #0 { -; CHECK-LABEL: @bar2( -; CHECK-NEXT:[[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT:tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT:ret i32 1 -; - %and = and i32 %a, 7 - %cmp = icmp eq i32 %and, 1 - tail call void @llvm.assume(i1 %cmp) - %and1 = and i32 %a, 3 - ret i32 %and1 -} - -define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 { -; CHECK-LABEL: @bar3( -; CHECK-NEXT: entry: -; CHECK-NEXT:tail call void @llvm.assume(i1 [[X:%.*]]) -; CHECK-NEXT:[[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT:tail call void @llvm
[llvm-branch-commits] [llvm] 509fa8e - [SCEV] recognize logical and/or pattern
Author: Juneyoung Lee Date: 2021-01-01T04:37:57+09:00 New Revision: 509fa8e02e25a610574c0fc2cceea1d350c35a66 URL: https://github.com/llvm/llvm-project/commit/509fa8e02e25a610574c0fc2cceea1d350c35a66 DIFF: https://github.com/llvm/llvm-project/commit/509fa8e02e25a610574c0fc2cceea1d350c35a66.diff LOG: [SCEV] recognize logical and/or pattern This patch makes SCEV recognize 'select A, B, false' and 'select A, true, B'. This is a performance improvement that will be helpful after unsound select -> and/or transformation is removed, as discussed in D93065. SCEV's answers for the select form should be a bit more conservative than the equivalent `and A, B` / `or A, B`. Take this example: https://alive2.llvm.org/ce/z/NsP9ue . To check whether it is valid for SCEV's computeExitLimit to return min(n, m) as ExactNotTaken value, I put llvm.assume at tgt. It fails because the exit limit becomes poison if n is zero and m is poison. This is problematic if e.g. the exit value of i is replaced with min(n, m). If either n or m is constant, we can revive the analysis again. I added relevant tests and put alive2 links there. If and is used instead, this is okay: https://alive2.llvm.org/ce/z/K9rbJk . Hence the existing analysis is sound. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93882 Added: llvm/test/Analysis/ScalarEvolution/exit-count-select.ll llvm/test/Analysis/ScalarEvolution/trip-count-andor-selectform.ll Modified: llvm/include/llvm/Analysis/ScalarEvolution.h llvm/lib/Analysis/ScalarEvolution.cpp Removed: diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index a7a24f086fbe..b3f199de2cfa 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1676,10 +1676,7 @@ class ScalarEvolution { computeExitLimitFromCondFromBinOp(ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates); - ExitLimit computeExitLimitFromCondFromBinOpHelper( - ExitLimitCacheTy &Cache, const Loop *L, BinaryOperator *BO, - bool EitherMayExit, bool ExitIfTrue, bool ControlsExit, - bool AllowPredicates, const Constant *NeutralElement); + /// Compute the number of times the backedge of the specified loop will /// execute if its exit condition were a conditional branch of the ICmpInst /// ExitCond and ExitIfTrue. If AllowPredicates is set, this call will try diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index b0ead7349ba5..3c284007cc2d 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -135,6 +135,7 @@ #include using namespace llvm; +using namespace PatternMatch; #define DEBUG_TYPE "scalar-evolution" @@ -7578,47 +7579,64 @@ ScalarEvolution::computeExitLimitFromCondFromBinOp( ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates) { // Check if the controlling expression for this loop is an And or Or. - if (auto *BO = dyn_cast(ExitCond)) { -if (BO->getOpcode() == Instruction::And) - return computeExitLimitFromCondFromBinOpHelper( - Cache, L, BO, !ExitIfTrue, ExitIfTrue, ControlsExit, AllowPredicates, - ConstantInt::get(BO->getType(), 1)); -if (BO->getOpcode() == Instruction::Or) - return computeExitLimitFromCondFromBinOpHelper( - Cache, L, BO, ExitIfTrue, ExitIfTrue, ControlsExit, AllowPredicates, - ConstantInt::get(BO->getType(), 0)); - } - return None; -} + Value *Op0, *Op1; + bool IsAnd = false; + if (match(ExitCond, m_LogicalAnd(m_Value(Op0), m_Value(Op1 +IsAnd = true; + else if (match(ExitCond, m_LogicalOr(m_Value(Op0), m_Value(Op1 +IsAnd = false; + else +return None; + + // EitherMayExit is true in these two cases: + // br (and Op0 Op1), loop, exit + // br (or Op0 Op1), exit, loop + bool EitherMayExit = IsAnd ^ ExitIfTrue; + ExitLimit EL0 = computeExitLimitFromCondCached(Cache, L, Op0, ExitIfTrue, + ControlsExit && !EitherMayExit, + AllowPredicates); + ExitLimit EL1 = computeExitLimitFromCondCached(Cache, L, Op1, ExitIfTrue, + ControlsExit && !EitherMayExit, + AllowPredicates); + + // Be robust against unsimplified IR for the form "op i1 X, NeutralElement" + const Constant *NeutralElement = ConstantInt::get(ExitCond->getType(), IsAnd); + if (isa(Op1)) +return Op1 == NeutralElement ? EL0 : EL1; + if (isa(Op0)) +return Op0 == NeutralElement ? EL1 : EL0; -ScalarEvolution::
[llvm-branch-commits] [llvm] 5cdf6ed - [CodeGen] recognize select form of and/ors when splitting branch conditions
Author: Juneyoung Lee Date: 2021-01-01T04:46:10+09:00 New Revision: 5cdf6ed744896a23ebc3f723ee2abcfc88137da0 URL: https://github.com/llvm/llvm-project/commit/5cdf6ed744896a23ebc3f723ee2abcfc88137da0 DIFF: https://github.com/llvm/llvm-project/commit/5cdf6ed744896a23ebc3f723ee2abcfc88137da0.diff LOG: [CodeGen] recognize select form of and/ors when splitting branch conditions Recently a few patches are made to move towards using select i1 instead of and/or i1 to represent "a && b"/"a || b" in C/C++. "a && b" in C/C++ does not evaluate b if a is false whereas 'and a, b' in IR evaluates b and uses its result regardless of the result of a. This is problematic because it can cause miscompilation if b was an erroneous operation (https://llvm.org/pr48353). In C/C++, the result is simply false because b is not evaluated, but in IR the result is poison. The discussion at D93065 has more context about this. This patch makes two branch-splitting optimizations (one in SelectionDAGBuilder, one in CodeGenPrepare) recognize select form of and/or as well using m_LogicalAnd/Or. Since it is CodeGen, I think this is semantically ok (at least as safe as what codegen already did). Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93853 Added: Modified: llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-condbr-lower-tree.ll llvm/test/CodeGen/AArch64/arm64_32.ll llvm/test/CodeGen/AArch64/fast-isel-branch-cond-split.ll Removed: diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 4a82c9570cc2..d64a8f26519f 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -7838,9 +7838,10 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) { // %cond2 = icmp|fcmp|binary instruction ... // %cond.or = or|and i1 %cond1, cond2 // br i1 %cond.or label %dest1, label %dest2" -BinaryOperator *LogicOp; +Instruction *LogicOp; BasicBlock *TBB, *FBB; -if (!match(BB.getTerminator(), m_Br(m_OneUse(m_BinOp(LogicOp)), TBB, FBB))) +if (!match(BB.getTerminator(), + m_Br(m_OneUse(m_Instruction(LogicOp)), TBB, FBB))) continue; auto *Br1 = cast(BB.getTerminator()); @@ -7853,17 +7854,22 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) { unsigned Opc; Value *Cond1, *Cond2; -if (match(LogicOp, m_And(m_OneUse(m_Value(Cond1)), - m_OneUse(m_Value(Cond2) +if (match(LogicOp, + m_LogicalAnd(m_OneUse(m_Value(Cond1)), m_OneUse(m_Value(Cond2) Opc = Instruction::And; -else if (match(LogicOp, m_Or(m_OneUse(m_Value(Cond1)), - m_OneUse(m_Value(Cond2) +else if (match(LogicOp, m_LogicalOr(m_OneUse(m_Value(Cond1)), +m_OneUse(m_Value(Cond2) Opc = Instruction::Or; else continue; -if (!match(Cond1, m_CombineOr(m_Cmp(), m_BinOp())) || -!match(Cond2, m_CombineOr(m_Cmp(), m_BinOp())) ) +auto IsGoodCond = [](Value *Cond) { + return match( + Cond, + m_CombineOr(m_Cmp(), m_CombineOr(m_LogicalAnd(m_Value(), m_Value()), + m_LogicalOr(m_Value(), m_Value(); +}; +if (!IsGoodCond(Cond1) || !IsGoodCond(Cond2)) continue; LLVM_DEBUG(dbgs() << "Before branch condition splitting\n"; BB.dump()); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index dde97ba599b9..c80821746c14 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -426,14 +426,19 @@ void IRTranslator::findMergedConditions( } const Instruction *BOp = dyn_cast(Cond); + const Value *BOpOp0, *BOpOp1; // Compute the effective opcode for Cond, taking into account whether it needs // to be inverted, e.g. // and (not (or A, B)), C // gets lowered as // and (and (not A, not B), C) - unsigned BOpc = 0; + Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0; if (BOp) { -BOpc = BOp->getOpcode(); +BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1))) + ? Instruction::And + : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1))) + ? Instruction::Or + : (Instruction::BinaryOps)0); if (InvertCond) { if (BOpc == Instruction::And) BOpc = Instruction::Or; @@ -443,11 +448,11 @@ void IRTranslator::findMergedConditions( } // If this node is not part of the or/and tree, emit it as a branch. - if (!BOp || !(isa(BO
[llvm-branch-commits] [llvm] 3c60e9b - Add tests for D93943 (NFC)
Author: Juneyoung Lee Date: 2021-01-01T05:59:52+09:00 New Revision: 3c60e9bac86804a32bf515b9381c91fb64d769f8 URL: https://github.com/llvm/llvm-project/commit/3c60e9bac86804a32bf515b9381c91fb64d769f8 DIFF: https://github.com/llvm/llvm-project/commit/3c60e9bac86804a32bf515b9381c91fb64d769f8.diff LOG: Add tests for D93943 (NFC) Added: Modified: llvm/test/Transforms/SimplifyCFG/switch_create.ll Removed: diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll index cc7a48904482..10689a03c398 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll @@ -469,6 +469,29 @@ define i32 @test10_select(i32 %mode, i1 %Cond) { ; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 ; CHECK-NEXT:[[B:%.*]] = icmp ne i32 [[MODE]], 51 ; CHECK-NEXT:[[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false +; CHECK-NEXT:[[D:%.*]] = select i1 [[C]], i1 [[COND:%.*]], i1 false +; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 +; CHECK-NEXT:ret i32 [[SPEC_SELECT]] +; + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = select i1 %A, i1 %B, i1 false + %D = select i1 %C, i1 %Cond, i1 false + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +} + +; TODO: %Cond doesn't need freeze +define i32 @test10_select_and(i32 %mode, i1 %Cond) { +; CHECK-LABEL: @test10_select_and( +; CHECK-NEXT: T: +; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 +; CHECK-NEXT:[[B:%.*]] = icmp ne i32 [[MODE]], 51 +; CHECK-NEXT:[[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false ; CHECK-NEXT:[[D:%.*]] = and i1 [[C]], [[COND:%.*]] ; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 ; CHECK-NEXT:ret i32 [[SPEC_SELECT]] @@ -485,6 +508,28 @@ F: } +define i32 @test10_select_nofreeze(i32 %mode, i1 noundef %Cond) { +; CHECK-LABEL: @test10_select_nofreeze( +; CHECK-NEXT: T: +; CHECK-NEXT:[[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 +; CHECK-NEXT:[[B:%.*]] = icmp ne i32 [[MODE]], 51 +; CHECK-NEXT:[[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false +; CHECK-NEXT:[[D:%.*]] = select i1 [[C]], i1 [[COND:%.*]], i1 false +; CHECK-NEXT:[[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 +; CHECK-NEXT:ret i32 [[SPEC_SELECT]] +; + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = select i1 %A, i1 %B, i1 false + %D = select i1 %C, i1 %Cond, i1 false + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +} + ; PR8780 define i32 @test11(i32 %bar) nounwind { ; CHECK-LABEL: @test11( ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] da1bd95 - Precommit a test for D92015 (NFC)
Author: Juneyoung Lee Date: 2021-01-01T22:35:57+09:00 New Revision: da1bd953faafe433a6fa259641973866fc6d934c URL: https://github.com/llvm/llvm-project/commit/da1bd953faafe433a6fa259641973866fc6d934c DIFF: https://github.com/llvm/llvm-project/commit/da1bd953faafe433a6fa259641973866fc6d934c.diff LOG: Precommit a test for D92015 (NFC) Added: llvm/test/CodeGen/X86/select-prof-codegen.ll Modified: Removed: diff --git a/llvm/test/CodeGen/X86/select-prof-codegen.ll b/llvm/test/CodeGen/X86/select-prof-codegen.ll new file mode 100644 index ..22f7d728847b --- /dev/null +++ b/llvm/test/CodeGen/X86/select-prof-codegen.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s + +; TODO: Compiling the select should not create 'seta - testb $1 - jump' sequence. +define i32 @f(i32 %x, i32 %y) { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:cmpl %esi, %edi +; CHECK-NEXT:seta %cl +; CHECK-NEXT:testb $1, %cl +; CHECK-NEXT:jne .LBB0_2 +; CHECK-NEXT: # %bb.1: # %select.false +; CHECK-NEXT:movl %esi, %eax +; CHECK-NEXT: .LBB0_2: # %select.end +; CHECK-NEXT:retq +entry: + %cmp = icmp ugt i32 %x, %y + %z = select i1 %cmp, i32 %x, i32 %y, !prof !0 + ret i32 %z +} + +!0 = !{!"branch_weights", i32 1, i32 2000} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c5a7e75 - Update *-inseltpoison.ll tests at Transforms/InstCombine/X86 by replacing undef with poison (NFC)
Author: Juneyoung Lee Date: 2021-01-03T22:40:05+09:00 New Revision: c5a7e75eb6b5129967f9b936425e5fd9633a42f5 URL: https://github.com/llvm/llvm-project/commit/c5a7e75eb6b5129967f9b936425e5fd9633a42f5 DIFF: https://github.com/llvm/llvm-project/commit/c5a7e75eb6b5129967f9b936425e5fd9633a42f5.diff LOG: Update *-inseltpoison.ll tests at Transforms/InstCombine/X86 by replacing undef with poison (NFC) Added: Modified: llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll llvm/test/Transforms/InstCombine/X86/x86-pshufb-inseltpoison.ll llvm/test/Transforms/InstCombine/X86/x86-sse4a-inseltpoison.ll llvm/test/Transforms/InstCombine/X86/x86-vector-shifts-inseltpoison.ll llvm/test/Transforms/InstCombine/X86/x86-vpermil-inseltpoison.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll index ff8842cd15ea..4cc89fc80f29 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll @@ -5,99 +5,99 @@ ; UNDEF Elts ; -define <8 x i16> @undef_packssdw_128() { -; CHECK-LABEL: @undef_packssdw_128( +define <8 x i16> @poison_packssdw_128() { +; CHECK-LABEL: @poison_packssdw_128( ; CHECK-NEXT:ret <8 x i16> undef ; - %1 = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> undef, <4 x i32> undef) + %1 = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> poison, <4 x i32> poison) ret <8 x i16> %1 } -define <8 x i16> @undef_packusdw_128() { -; CHECK-LABEL: @undef_packusdw_128( +define <8 x i16> @poison_packusdw_128() { +; CHECK-LABEL: @poison_packusdw_128( ; CHECK-NEXT:ret <8 x i16> undef ; - %1 = call <8 x i16> @llvm.x86.sse41.packusdw(<4 x i32> undef, <4 x i32> undef) + %1 = call <8 x i16> @llvm.x86.sse41.packusdw(<4 x i32> poison, <4 x i32> poison) ret <8 x i16> %1 } -define <16 x i8> @undef_packsswb_128() { -; CHECK-LABEL: @undef_packsswb_128( +define <16 x i8> @poison_packsswb_128() { +; CHECK-LABEL: @poison_packsswb_128( ; CHECK-NEXT:ret <16 x i8> undef ; - %1 = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> undef, <8 x i16> undef) + %1 = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> poison, <8 x i16> poison) ret <16 x i8> %1 } -define <16 x i8> @undef_packuswb_128() { -; CHECK-LABEL: @undef_packuswb_128( +define <16 x i8> @poison_packuswb_128() { +; CHECK-LABEL: @poison_packuswb_128( ; CHECK-NEXT:ret <16 x i8> undef ; - %1 = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> undef, <8 x i16> undef) + %1 = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> poison, <8 x i16> poison) ret <16 x i8> %1 } -define <16 x i16> @undef_packssdw_256() { -; CHECK-LABEL: @undef_packssdw_256( +define <16 x i16> @poison_packssdw_256() { +; CHECK-LABEL: @poison_packssdw_256( ; CHECK-NEXT:ret <16 x i16> undef ; - %1 = call <16 x i16> @llvm.x86.avx2.packssdw(<8 x i32> undef, <8 x i32> undef) + %1 = call <16 x i16> @llvm.x86.avx2.packssdw(<8 x i32> poison, <8 x i32> poison) ret <16 x i16> %1 } -define <16 x i16> @undef_packusdw_256() { -; CHECK-LABEL: @undef_packusdw_256( +define <16 x i16> @poison_packusdw_256() { +; CHECK-LABEL: @poison_packusdw_256( ; CHECK-NEXT:ret <16 x i16> undef ; - %1 = call <16 x i16> @llvm.x86.avx2.packusdw(<8 x i32> undef, <8 x i32> undef) + %1 = call <16 x i16> @llvm.x86.avx2.packusdw(<8 x i32> poison, <8 x i32> poison) ret <16 x i16> %1 } -define <32 x i8> @undef_packsswb_256() { -; CHECK-LABEL: @undef_packsswb_256( +define <32 x i8> @poison_packsswb_256() { +; CHECK-LABEL: @poison_packsswb_256( ; CHECK-NEXT:ret <32 x i8> undef ; - %1 = call <32 x i8> @llvm.x86.avx2.packsswb(<16 x i16> undef, <16 x i16> undef) + %1 = call <32 x i8> @llvm.x86.avx2.packsswb(<16 x i16> poison, <16 x i16> poison) ret <32 x i8> %1 } -define <32 x i8> @undef_packuswb_256() { -; CHECK-LABEL: @undef_packuswb_256( +define <32 x i8> @poison_packuswb_256() { +; CHECK-LABEL: @poison_packuswb_256( ; CHECK-NEXT:ret <32 x i8> undef ; - %1 = call <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> undef, <16 x i16> undef) + %1 = call <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> poison, <16 x i16> poison) ret <32 x i8> %1 } -define <32 x i16> @undef_packssdw_512() { -; CHECK-LABEL: @undef_packssdw_512( +define <32 x i16> @poison_packssdw_512() { +; CHECK-LABEL: @poison_packssdw_512( ; CHECK-NEXT:ret <32 x i16> undef ; - %1 = call <32 x i16> @llvm.x86.avx512.packssdw.512(<16 x i32> undef, <16 x i32> undef) + %1 = call <32 x i16> @llvm.x86.avx512.packssdw.512(<16 x i32> poison, <16 x i32> poison) ret <32 x i16> %1 } -define <32 x i16> @undef_packusdw_512() { -; CHECK-LABEL: @undef_packusdw_512( +define <32 x i16> @poison_packusdw_512() { +; CHECK-LABEL: @poison_packusdw_512( ; CHECK-NEXT
[llvm-branch-commits] [llvm] 1fc992b - [Scalarizer] Use poison as insertelement's placeholder
Author: Juneyoung Lee Date: 2021-01-04T00:35:28+09:00 New Revision: 1fc992bd864aa7e73615a47e72e82e2cf7ac73ef URL: https://github.com/llvm/llvm-project/commit/1fc992bd864aa7e73615a47e72e82e2cf7ac73ef DIFF: https://github.com/llvm/llvm-project/commit/1fc992bd864aa7e73615a47e72e82e2cf7ac73ef.diff LOG: [Scalarizer] Use poison as insertelement's placeholder This patch makes Scalarizer to use poison as insertelement's placeholder. It contains two changes in Scalarizer.cpp, and the both changes does not change the semantics of the optimized program. It is because the placeholder value (poison) is already completely hidden by following insertelement instructions. The first change at visitBitCastInst() creates poison vector of MidTy and consecutively inserts FanIn times, which is # of elems of MidTy. The second change at ScalarizerVisitor::finish() creates poison with Op->getType(), and it is filled with Count insertelements. The test diffs show that the poison value is never exposed after insertelements. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93989 Added: Modified: llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/test/Transforms/Scalarizer/basic-inseltpoison.ll llvm/test/Transforms/Scalarizer/basic.ll llvm/test/Transforms/Scalarizer/constant-insertelement.ll llvm/test/Transforms/Scalarizer/intrinsics.ll llvm/test/Transforms/Scalarizer/order-bug-inseltpoison.ll llvm/test/Transforms/Scalarizer/order-bug.ll llvm/test/Transforms/Scalarizer/scatter-order.ll llvm/test/Transforms/Scalarizer/variable-extractelement.ll llvm/test/Transforms/Scalarizer/variable-insertelement.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index c7fe21f2a3da..c95984fe198f 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -733,7 +733,7 @@ bool ScalarizerVisitor::visitBitCastInst(BitCastInst &BCI) { auto *MidTy = FixedVectorType::get(SrcVT->getElementType(), FanIn); unsigned Op0I = 0; for (unsigned ResI = 0; ResI < DstNumElems; ++ResI) { - Value *V = UndefValue::get(MidTy); + Value *V = PoisonValue::get(MidTy); for (unsigned MidI = 0; MidI < FanIn; ++MidI) V = Builder.CreateInsertElement(V, Op0[Op0I++], Builder.getInt32(MidI), BCI.getName() + ".i" + Twine(ResI) @@ -932,7 +932,7 @@ bool ScalarizerVisitor::finish() { if (!Op->use_empty()) { // The value is still needed, so recreate it using a series of // InsertElements. - Value *Res = UndefValue::get(Op->getType()); + Value *Res = PoisonValue::get(Op->getType()); if (auto *Ty = dyn_cast(Op->getType())) { BasicBlock *BB = Op->getParent(); unsigned Count = cast(Ty)->getNumElements(); diff --git a/llvm/test/Transforms/Scalarizer/basic-inseltpoison.ll b/llvm/test/Transforms/Scalarizer/basic-inseltpoison.ll index d785764e3366..2b501cfd0a7e 100644 --- a/llvm/test/Transforms/Scalarizer/basic-inseltpoison.ll +++ b/llvm/test/Transforms/Scalarizer/basic-inseltpoison.ll @@ -33,7 +33,7 @@ define void @f1(<4 x float> %init, <4 x float> *%base, i32 %count) { ; CHECK: %add.i1 = fadd float %val.i1, %val.i3 ; CHECK: %add.i2 = fadd float %acc.i0, %acc.i2 ; CHECK: %add.i3 = fadd float %acc.i1, %acc.i3 -; CHECK: %add.upto0 = insertelement <4 x float> undef, float %add.i0, i32 0 +; CHECK: %add.upto0 = insertelement <4 x float> poison, float %add.i0, i32 0 ; CHECK: %add.upto1 = insertelement <4 x float> %add.upto0, float %add.i1, i32 1 ; CHECK: %add.upto2 = insertelement <4 x float> %add.upto1, float %add.i2, i32 2 ; CHECK: %add = insertelement <4 x float> %add.upto2, float %add.i3, i32 3 @@ -247,7 +247,7 @@ define <4 x float> @f6(<4 x float> %x) { ; CHECK: %res.i2 = fadd float %x.i2, 3.0{{[e+0]*}}, !fpmath ![[TAG]] ; CHECK: %x.i3 = extractelement <4 x float> %x, i32 3 ; CHECK: %res.i3 = fadd float %x.i3, 4.0{{[e+0]*}}, !fpmath ![[TAG]] -; CHECK: %res.upto0 = insertelement <4 x float> undef, float %res.i0, i32 0 +; CHECK: %res.upto0 = insertelement <4 x float> poison, float %res.i0, i32 0 ; CHECK: %res.upto1 = insertelement <4 x float> %res.upto0, float %res.i1, i32 1 ; CHECK: %res.upto2 = insertelement <4 x float> %res.upto1, float %res.i2, i32 2 ; CHECK: %res = insertelement <4 x float> %res.upto2, float %res.i3, i32 3 @@ -403,7 +403,7 @@ define <4 x float> @f14(<4 x float> %acc, i32 %count) { ; CHECK: %this_acc.i2 = phi float [ %acc.i2, %entry ], [ %next_acc.i2, %loop ] ; CHECK: %this_acc.i3 = phi float [ %acc.i3, %entry ], [ %next_acc.i3, %loop ] ; CHECK: %this_count = phi i32 [ %count, %entry ], [ %next_count, %loop ] -; CHECK: %this_acc.upto0 = insertelement <4 x float> undef, float %this_acc.i0, i32 0 +; CHECK: %this_acc.upto0 = insertelemen
[llvm-branch-commits] [llvm] 2139958 - [InstSimplify] Return poison if insertelement touches out of bounds
Author: Juneyoung Lee Date: 2021-01-04T00:43:02+09:00 New Revision: 2139958b53440074fcab9bb2de15e6ec13cc18eb URL: https://github.com/llvm/llvm-project/commit/2139958b53440074fcab9bb2de15e6ec13cc18eb DIFF: https://github.com/llvm/llvm-project/commit/2139958b53440074fcab9bb2de15e6ec13cc18eb.diff LOG: [InstSimplify] Return poison if insertelement touches out of bounds This is a simple patch that updates InstSimplify to return poison if the index is/can be out-of-bounds Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93990 Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll llvm/test/Transforms/InstCombine/vector_insertelt_shuffle-inseltpoison.ll llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll llvm/test/Transforms/InstSimplify/insertelement.ll llvm/test/Transforms/InstSimplify/vscale-inseltpoison.ll llvm/test/Transforms/InstSimplify/vscale.ll Removed: diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 9fed2600b3ab..eb945c60cf94 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4385,16 +4385,16 @@ Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx, if (VecC && ValC && IdxC) return ConstantExpr::getInsertElement(VecC, ValC, IdxC); - // For fixed-length vector, fold into undef if index is out of bounds. + // For fixed-length vector, fold into poison if index is out of bounds. if (auto *CI = dyn_cast(Idx)) { if (isa(Vec->getType()) && CI->uge(cast(Vec->getType())->getNumElements())) - return UndefValue::get(Vec->getType()); + return PoisonValue::get(Vec->getType()); } // If index is undef, it might be out of bounds (see above case) if (Q.isUndefValue(Idx)) -return UndefValue::get(Vec->getType()); +return PoisonValue::get(Vec->getType()); // If the scalar is undef, and there is no risk of propagating poison from the // vector value, simplify to the vector value. diff --git a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll index 9559c61dda00..f3b95ed07d44 100644 --- a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll +++ b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll @@ -34,7 +34,7 @@ declare void @llvm.assume(i1) define <4 x double> @inselt_bad_index(<4 x double> %a) { ; CHECK-LABEL: @inselt_bad_index( -; CHECK-NEXT:ret <4 x double> undef +; CHECK-NEXT:ret <4 x double> poison ; %I = insertelement <4 x double> %a, double 0.0, i64 4294967296 ret <4 x double> %I diff --git a/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle-inseltpoison.ll index b08e4a7db125..eaa83d4c03f4 100644 --- a/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle-inseltpoison.ll @@ -54,10 +54,10 @@ define <4 x float> @bazz(<4 x float> %x, i32 %a) { ret <4 x float> %ins6 } -; Out of bounds index folds to undef +; Out of bounds index folds to poison define <4 x float> @bazzz(<4 x float> %x) { ; CHECK-LABEL: @bazzz( -; CHECK-NEXT:ret <4 x float> +; CHECK-NEXT:ret <4 x float> ; %ins1 = insertelement<4 x float> %x, float 1.0, i32 5 %ins2 = insertelement<4 x float> %ins1, float 2.0, i32 2 @@ -66,7 +66,7 @@ define <4 x float> @bazzz(<4 x float> %x) { define <4 x float> @ba(<4 x float> %x) { ; CHECK-LABEL: @ba( -; CHECK-NEXT:ret <4 x float> +; CHECK-NEXT:ret <4 x float> ; %ins1 = insertelement<4 x float> %x, float 1.0, i32 undef %ins2 = insertelement<4 x float> %ins1, float 2.0, i32 2 diff --git a/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll b/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll index 30150af6209b..2635c627c160 100644 --- a/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll @@ -54,10 +54,10 @@ define <4 x float> @bazz(<4 x float> %x, i32 %a) { ret <4 x float> %ins6 } -; Out of bounds index folds to undef +; Out of bounds index folds to poison define <4 x float> @bazzz(<4 x float> %x) { ; CHECK-LABEL: @bazzz( -; CHECK-NEXT:ret <4 x float> +; CHECK-NEXT:ret <4 x float> ; %ins1 = insertelement<4 x float> %x, float 1.0, i32 5 %ins2 = insertelement<4 x float> %ins1, float 2.0, i32 2 @@ -66,7 +66,7 @@ define <4 x float> @bazzz(<4 x float> %x) { define <4 x float> @ba(<4 x float> %x) { ; CHECK-LABEL: @ba( -; CHECK-NEXT:ret <4 x float> +; CHECK-NEXT:ret <4 x float> ; %ins1 = insertelement<4 x float> %x, float 1.0, i32 undef %
[llvm-branch-commits] [llvm] 49c2d70 - [X86] Make deinterleave8bitStride3 use unary CreateShuffleVector
Author: Juneyoung Lee Date: 2021-01-04T02:10:51+09:00 New Revision: 49c2d703d344e8d259a4aee38c8ade1df34bc54a URL: https://github.com/llvm/llvm-project/commit/49c2d703d344e8d259a4aee38c8ade1df34bc54a DIFF: https://github.com/llvm/llvm-project/commit/49c2d703d344e8d259a4aee38c8ade1df34bc54a.diff LOG: [X86] Make deinterleave8bitStride3 use unary CreateShuffleVector This patch makes X86InterleavedAccessGroup::deinterleave8bitStride3 use the unary CreateShuffleVector. This is a continuation of D93923. There were a few missing replacements. IIUC, this patch does not cause change in the generated programs' semantics because the function inserts shufflevectors that only choose elements from the first vector. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93993 Added: Modified: llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad-inseltpoison.ll llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad.ll llvm/test/Transforms/InterleavedAccess/X86/interleavedStore-inseltpoison.ll llvm/test/Transforms/InterleavedAccess/X86/interleavedStore.ll Removed: diff --git a/llvm/lib/Target/X86/X86InterleavedAccess.cpp b/llvm/lib/Target/X86/X86InterleavedAccess.cpp index 5546f27b9488..95655dd4723b 100644 --- a/llvm/lib/Target/X86/X86InterleavedAccess.cpp +++ b/llvm/lib/Target/X86/X86InterleavedAccess.cpp @@ -44,8 +44,8 @@ namespace { /// E.g. A group of interleaving access loads (Factor = 2; accessing every /// other element) ///%wide.vec = load <8 x i32>, <8 x i32>* %ptr -///%v0 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <0, 2, 4, 6> -///%v1 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <1, 3, 5, 7> +///%v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6> +///%v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7> class X86InterleavedAccessGroup { /// Reference to the wide-load instruction of an interleaved access /// group. @@ -576,8 +576,7 @@ void X86InterleavedAccessGroup::deinterleave8bitStride3( // Vec[2]= b5 b6 b7 c5 c6 c7 a6 a7 for (int i = 0; i < 3; i++) -Vec[i] = Builder.CreateShuffleVector( -Vec[i], UndefValue::get(Vec[0]->getType()), VPShuf); +Vec[i] = Builder.CreateShuffleVector(Vec[i], VPShuf); // TempVector[0]= a6 a7 a0 a1 a2 b0 b1 b2 // TempVector[1]= c0 c1 c2 c3 c4 a3 a4 a5 @@ -599,10 +598,8 @@ void X86InterleavedAccessGroup::deinterleave8bitStride3( // TransposedMatrix[1]= b0 b1 b2 b3 b4 b5 b6 b7 // TransposedMatrix[2]= c0 c1 c2 c3 c4 c5 c6 c7 - Value *TempVec = Builder.CreateShuffleVector( - Vec[1], UndefValue::get(Vec[1]->getType()), VPAlign3); - TransposedMatrix[0] = Builder.CreateShuffleVector( - Vec[0], UndefValue::get(Vec[1]->getType()), VPAlign2); + Value *TempVec = Builder.CreateShuffleVector(Vec[1], VPAlign3); + TransposedMatrix[0] = Builder.CreateShuffleVector(Vec[0], VPAlign2); TransposedMatrix[1] = VecElems == 8 ? Vec[2] : TempVec; TransposedMatrix[2] = VecElems == 8 ? TempVec : Vec[2]; } @@ -659,10 +656,8 @@ void X86InterleavedAccessGroup::interleave8bitStride3( // Vec[1]= c5 c6 c7 c0 c1 c2 c3 c4 // Vec[2]= b0 b1 b2 b3 b4 b5 b6 b7 - Vec[0] = Builder.CreateShuffleVector( - InVec[0], UndefValue::get(InVec[0]->getType()), VPAlign2); - Vec[1] = Builder.CreateShuffleVector( - InVec[1], UndefValue::get(InVec[1]->getType()), VPAlign3); + Vec[0] = Builder.CreateShuffleVector(InVec[0], VPAlign2); + Vec[1] = Builder.CreateShuffleVector(InVec[1], VPAlign3); Vec[2] = InVec[2]; // Vec[0]= a6 a7 a0 a1 a2 b0 b1 b2 diff --git a/llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad-inseltpoison.ll b/llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad-inseltpoison.ll index f713918292dc..7fbf34aa1db4 100644 --- a/llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad-inseltpoison.ll +++ b/llvm/test/Transforms/InterleavedAccess/X86/interleavedLoad-inseltpoison.ll @@ -20,17 +20,17 @@ define <32 x i8> @interleaved_load_vf32_i8_stride3(<96 x i8>* %ptr){ ; CHECK-NEXT:[[TMP14:%.*]] = shufflevector <16 x i8> [[TMP3]], <16 x i8> [[TMP9]], <32 x i32> ; CHECK-NEXT:[[TMP15:%.*]] = shufflevector <16 x i8> [[TMP5]], <16 x i8> [[TMP11]], <32 x i32> ; CHECK-NEXT:[[TMP16:%.*]] = shufflevector <16 x i8> [[TMP7]], <16 x i8> [[TMP13]], <32 x i32> -; CHECK-NEXT:[[TMP17:%.*]] = shufflevector <32 x i8> [[TMP14]], <32 x i8> undef, <32 x i32> -; CHECK-NEXT:[[TMP18:%.*]] = shufflevector <32 x i8> [[TMP15]], <32 x i8> undef, <32 x i32> -; CHECK-NEXT:[[TMP19:%.*]] = shufflevector <32 x i8> [[TMP16]], <32 x i8> undef, <32 x i32> +; CHECK-NEXT:[[TMP17:%.*]] = shufflevector <32 x i8> [[TMP14]], <32 x i8> poison, <32 x i32> +; CHECK-NEXT:[[TMP18:%.*]] = shufflevector <32 x i8> [[TMP15]], <32 x i8> p
[llvm-branch-commits] [llvm] abbef2f - [ValueTracking] isGuaranteedNotToBePoison should return true on undef
Author: Juneyoung Lee Date: 2021-01-05T06:50:02+09:00 New Revision: abbef2fd46d48a0d92d86f0c00fa2973f8ae2c85 URL: https://github.com/llvm/llvm-project/commit/abbef2fd46d48a0d92d86f0c00fa2973f8ae2c85 DIFF: https://github.com/llvm/llvm-project/commit/abbef2fd46d48a0d92d86f0c00fa2973f8ae2c85.diff LOG: [ValueTracking] isGuaranteedNotToBePoison should return true on undef This is a one-line fix to isGuaranteedNotToBePoison to return true if undef is given. Added: Modified: llvm/lib/Analysis/ValueTracking.cpp llvm/unittests/Analysis/ValueTrackingTest.cpp Removed: diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 303240d03c72..e15d4f0e4b07 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4888,7 +4888,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V, if (auto *C = dyn_cast(V)) { if (isa(C)) - return PoisonOnly; + return PoisonOnly && !isa(C); if (isa(C) || isa(C) || isa(V) || isa(C) || isa(C)) diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 009166a24a1f..0d6577452560 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -884,6 +884,10 @@ TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) { " ret void\n" "}\n"); EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(A), true); + EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(UndefValue::get(IntegerType::get(Context, 8))), false); + EXPECT_EQ(isGuaranteedNotToBeUndefOrPoison(PoisonValue::get(IntegerType::get(Context, 8))), false); + EXPECT_EQ(isGuaranteedNotToBePoison(UndefValue::get(IntegerType::get(Context, 8))), true); + EXPECT_EQ(isGuaranteedNotToBePoison(PoisonValue::get(IntegerType::get(Context, 8))), false); } TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] f28b026 - [InstSimplify] add a test for gep with poison operand (NFC)
Author: Juneyoung Lee Date: 2021-01-05T11:03:11+09:00 New Revision: f28b026d32ca20208e24cab3aabb9d9fb0f1948a URL: https://github.com/llvm/llvm-project/commit/f28b026d32ca20208e24cab3aabb9d9fb0f1948a DIFF: https://github.com/llvm/llvm-project/commit/f28b026d32ca20208e24cab3aabb9d9fb0f1948a.diff LOG: [InstSimplify] add a test for gep with poison operand (NFC) Added: Modified: llvm/test/Transforms/InstSimplify/gep.ll Removed: diff --git a/llvm/test/Transforms/InstSimplify/gep.ll b/llvm/test/Transforms/InstSimplify/gep.ll index f60f0cb7fdca..804ce7f10a8c 100644 --- a/llvm/test/Transforms/InstSimplify/gep.ll +++ b/llvm/test/Transforms/InstSimplify/gep.ll @@ -218,7 +218,7 @@ define @ptr_idx_mix_scalar_scalable_vector() { ; Check ConstantExpr::getGetElementPtr() using ElementCount for size queries - end. -; TODO: this should return poison +; TODO: these should return poison define i8* @poison() { ; CHECK-LABEL: @poison( @@ -227,3 +227,12 @@ define i8* @poison() { %v = getelementptr i8, i8* poison, i64 1 ret i8* %v } + +define i8* @poison2(i8* %baseptr) { +; CHECK-LABEL: @poison2( +; CHECK-NEXT:[[V:%.*]] = getelementptr i8, i8* [[BASEPTR:%.*]], i64 poison +; CHECK-NEXT:ret i8* [[V]] +; + %v = getelementptr i8, i8* %baseptr, i64 poison + ret i8* %v +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] f665a8c - [InstSimplify] gep with poison operand is poison
Author: Juneyoung Lee Date: 2021-01-05T11:07:49+09:00 New Revision: f665a8c5b8b42d88f89e1a3594b7d410ef206c32 URL: https://github.com/llvm/llvm-project/commit/f665a8c5b8b42d88f89e1a3594b7d410ef206c32 DIFF: https://github.com/llvm/llvm-project/commit/f665a8c5b8b42d88f89e1a3594b7d410ef206c32.diff LOG: [InstSimplify] gep with poison operand is poison This is a tiny update to fold gep poison into poison. :) Alive2 proofs: https://alive2.llvm.org/ce/z/7Nwdri https://alive2.llvm.org/ce/z/sDP4sC Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstSimplify/gep.ll Removed: diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index dfaf36a96953..659b71fae6a0 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4242,6 +4242,11 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, else if (VectorType *VT = dyn_cast(Ops[1]->getType())) GEPTy = VectorType::get(GEPTy, VT->getElementCount()); + // getelementptr poison, idx -> poison + // getelementptr baseptr, poison -> poison + if (any_of(Ops, [](const auto *V) { return isa(V); })) +return PoisonValue::get(GEPTy); + if (Q.isUndefValue(Ops[0])) return UndefValue::get(GEPTy); diff --git a/llvm/test/Transforms/InstSimplify/gep.ll b/llvm/test/Transforms/InstSimplify/gep.ll index 804ce7f10a8c..e6670e4a9345 100644 --- a/llvm/test/Transforms/InstSimplify/gep.ll +++ b/llvm/test/Transforms/InstSimplify/gep.ll @@ -222,7 +222,7 @@ define @ptr_idx_mix_scalar_scalable_vector() { define i8* @poison() { ; CHECK-LABEL: @poison( -; CHECK-NEXT:ret i8* undef +; CHECK-NEXT:ret i8* poison ; %v = getelementptr i8, i8* poison, i64 1 ret i8* %v @@ -230,8 +230,7 @@ define i8* @poison() { define i8* @poison2(i8* %baseptr) { ; CHECK-LABEL: @poison2( -; CHECK-NEXT:[[V:%.*]] = getelementptr i8, i8* [[BASEPTR:%.*]], i64 poison -; CHECK-NEXT:ret i8* [[V]] +; CHECK-NEXT:ret i8* poison ; %v = getelementptr i8, i8* %baseptr, i64 poison ret i8* %v ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 29f8628 - [Constant] Add containsPoisonElement
Author: Juneyoung Lee Date: 2021-01-06T12:10:33+09:00 New Revision: 29f8628d1fc8d96670e13562c4d92fc916bd0ce1 URL: https://github.com/llvm/llvm-project/commit/29f8628d1fc8d96670e13562c4d92fc916bd0ce1 DIFF: https://github.com/llvm/llvm-project/commit/29f8628d1fc8d96670e13562c4d92fc916bd0ce1.diff LOG: [Constant] Add containsPoisonElement This patch - Adds containsPoisonElement that checks existence of poison in constant vector elements, - Renames containsUndefElement to containsUndefOrPoisonElement to clarify its behavior & updates its uses properly With this patch, isGuaranteedNotToBeUndefOrPoison's tests w.r.t constant vectors are added because its analysis is improved. Thanks! Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D94053 Added: Modified: llvm/include/llvm/IR/Constant.h llvm/lib/Analysis/ValueTracking.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp llvm/unittests/Analysis/ValueTrackingTest.cpp llvm/unittests/IR/ConstantsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h index 97650c2051ca..0190aca27b72 100644 --- a/llvm/include/llvm/IR/Constant.h +++ b/llvm/include/llvm/IR/Constant.h @@ -101,11 +101,15 @@ class Constant : public User { /// lane, the constants still match. bool isElementWiseEqual(Value *Y) const; - /// Return true if this is a vector constant that includes any undefined - /// elements. Since it is impossible to inspect a scalable vector element- - /// wise at compile time, this function returns true only if the entire - /// vector is undef - bool containsUndefElement() const; + /// Return true if this is a vector constant that includes any undef or + /// poison elements. Since it is impossible to inspect a scalable vector + /// element- wise at compile time, this function returns true only if the + /// entire vector is undef or poison. + bool containsUndefOrPoisonElement() const; + + /// Return true if this is a vector constant that includes any poison + /// elements. + bool containsPoisonElement() const; /// Return true if this is a fixed width vector constant that includes /// any constant expressions. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e15d4f0e4b07..1c75c5fbd0db 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4895,7 +4895,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V, return true; if (C->getType()->isVectorTy() && !isa(C)) - return (PoisonOnly || !C->containsUndefElement()) && + return (PoisonOnly ? !C->containsPoisonElement() + : !C->containsUndefOrPoisonElement()) && !C->containsConstantExpression(); } @@ -5636,10 +5637,10 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, // elements because those can not be back-propagated for analysis. Value *OutputZeroVal = nullptr; if (match(TrueVal, m_AnyZeroFP()) && !match(FalseVal, m_AnyZeroFP()) && -!cast(TrueVal)->containsUndefElement()) +!cast(TrueVal)->containsUndefOrPoisonElement()) OutputZeroVal = TrueVal; else if (match(FalseVal, m_AnyZeroFP()) && !match(TrueVal, m_AnyZeroFP()) && - !cast(FalseVal)->containsUndefElement()) + !cast(FalseVal)->containsUndefOrPoisonElement()) OutputZeroVal = FalseVal; if (OutputZeroVal) { diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 47745689ba2d..03cb108cc485 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -811,7 +811,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, return true; if (C->getType()->isVectorTy()) - return !C->containsUndefElement() && !C->containsConstantExpression(); + return !C->containsPoisonElement() && !C->containsConstantExpression(); // TODO: Recursively analyze aggregates or other constants. return false; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index a38302d17937..5aa819dda2b3 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -304,31 +304,42 @@ bool Constant::isElementWiseEqual(Value *Y) const { return isa(CmpEq) || match(CmpEq, m_One()); } -bool Constant::containsUndefElement() const { - if (auto *VTy = dyn_cast(getType())) { -if (isa(this)) +static bool +containsUndefinedElement(const Constant *C, + function_ref HasFn) { + if (auto *VTy = dyn_cast(C->getType())) { +if (HasFn(C)) return true; -if (isa(this)) +if (isa(C)) return false; -if (isa(getType())) +if (isa(C->getType()))
[llvm-branch-commits] [llvm] 8871a4b - [Constant] Update ConstantVector::get to return poison if all input elems are poison
Author: Juneyoung Lee Date: 2021-01-07T09:26:07+09:00 New Revision: 8871a4b4cab8a56fd6ff12fd024002c3c79128b3 URL: https://github.com/llvm/llvm-project/commit/8871a4b4cab8a56fd6ff12fd024002c3c79128b3 DIFF: https://github.com/llvm/llvm-project/commit/8871a4b4cab8a56fd6ff12fd024002c3c79128b3.diff LOG: [Constant] Update ConstantVector::get to return poison if all input elems are poison The diff was reviewed at D93994 Added: Modified: llvm/lib/IR/Constants.cpp llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll llvm/test/Transforms/VectorCombine/X86/insert-binop.ll Removed: diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 5aa819dda2b3..ba5e1ca3cdfb 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1339,17 +1339,20 @@ Constant *ConstantVector::getImpl(ArrayRef V) { Constant *C = V[0]; bool isZero = C->isNullValue(); bool isUndef = isa(C); + bool isPoison = isa(C); if (isZero || isUndef) { for (unsigned i = 1, e = V.size(); i != e; ++i) if (V[i] != C) { -isZero = isUndef = false; +isZero = isUndef = isPoison = false; break; } } if (isZero) return ConstantAggregateZero::get(T); + if (isPoison) +return PoisonValue::get(T); if (isUndef) return UndefValue::get(T); diff --git a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll index 4cc89fc80f29..0327e2866625 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-pack-inseltpoison.ll @@ -244,7 +244,7 @@ define <16 x i8> @elts_packsswb_128(<8 x i16> %a0, <8 x i16> %a1) { define <16 x i8> @elts_packuswb_128(<8 x i16> %a0, <8 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_128( -; CHECK-NEXT:ret <16 x i8> undef +; CHECK-NEXT:ret <16 x i8> poison ; %1 = insertelement <8 x i16> poison, i16 0, i32 0 %2 = insertelement <8 x i16> poison, i16 0, i32 0 @@ -293,7 +293,7 @@ define <32 x i8> @elts_packsswb_256(<16 x i16> %a0, <16 x i16> %a1) { define <32 x i8> @elts_packuswb_256(<16 x i16> %a0, <16 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_256( -; CHECK-NEXT:ret <32 x i8> undef +; CHECK-NEXT:ret <32 x i8> poison ; %1 = insertelement <16 x i16> poison, i16 0, i32 1 %2 = insertelement <16 x i16> poison, i16 0, i32 0 @@ -344,7 +344,7 @@ define <64 x i8> @elts_packsswb_512(<32 x i16> %a0, <32 x i16> %a1) { define <64 x i8> @elts_packuswb_512(<32 x i16> %a0, <32 x i16> %a1) { ; CHECK-LABEL: @elts_packuswb_512( -; CHECK-NEXT:ret <64 x i8> undef +; CHECK-NEXT:ret <64 x i8> poison ; %1 = insertelement <32 x i16> poison, i16 0, i32 1 %2 = insertelement <32 x i16> poison, i16 0, i32 0 diff --git a/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll b/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll index 505f16786b60..fd97b2ea6b4a 100644 --- a/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/scalarization.ll @@ -27,7 +27,7 @@ define <4 x i32> @square(<4 x i32> %num, i32 %y, i32 %x, i32 %h, i32 %k, i32 %w, ; CHECK-NEXT:[[DOTSCALAR6:%.*]] = add i32 [[DOTSCALAR5]], [[DIV9]] ; CHECK-NEXT:[[DOTSCALAR7:%.*]] = add i32 [[DOTSCALAR6]], [[MUL21]] ; CHECK-NEXT:[[DOTSCALAR8:%.*]] = add i32 [[DOTSCALAR7]], 317425 -; CHECK-NEXT:[[TMP1:%.*]] = insertelement <4 x i32> undef, i32 [[DOTSCALAR8]], i64 0 +; CHECK-NEXT:[[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[DOTSCALAR8]], i64 0 ; CHECK-NEXT:[[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer ; CHECK-NEXT:[[ADD29:%.*]] = add <4 x i32> [[TMP2]], [[NUM:%.*]] ; CHECK-NEXT:ret <4 x i32> [[ADD29]] diff --git a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll index ac6ece368ff0..54e84394d30d 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int-inseltpoison.ll @@ -425,7 +425,7 @@ define <8 x i32> @sdiv_v8i32_undefs(<8 x i32> %a) { ; CHECK-NEXT:[[AB5:%.*]] = sdiv i32 [[A5]], 4 ; CHECK-NEXT:[[AB6:%.*]] = sdiv i32 [[A6]], 8 ; CHECK-NEXT:[[AB7:%.*]] = sdiv i32 [[A7]], 16 -; CHECK-NEXT:[[TMP1:%.*]] = insertelement <8 x i32> , i32 [[AB1]], i32 1 +; CHECK-NEXT:[[TMP1:%.*]] = insertelement <8 x i32> poison, i32 [[AB1]], i32 1 ; CHECK-NEXT:[[TMP2:%.*]] = insertelement <8 x i32> [[TMP1]],
[llvm-branch-commits] [llvm] c95f398 - [Constant] Add tests for ConstantVector::get (NFC)
Author: Juneyoung Lee Date: 2021-01-07T10:08:01+09:00 New Revision: c95f39891a282ebf36199c73b705d4a2c78a46ce URL: https://github.com/llvm/llvm-project/commit/c95f39891a282ebf36199c73b705d4a2c78a46ce DIFF: https://github.com/llvm/llvm-project/commit/c95f39891a282ebf36199c73b705d4a2c78a46ce.diff LOG: [Constant] Add tests for ConstantVector::get (NFC) Added: Modified: llvm/unittests/IR/ConstantsTest.cpp Removed: diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp index afae154cca90..9eabc7c55638 100644 --- a/llvm/unittests/IR/ConstantsTest.cpp +++ b/llvm/unittests/IR/ConstantsTest.cpp @@ -631,9 +631,17 @@ TEST(ConstantsTest, isElementWiseEqual) { Type *Int32Ty = Type::getInt32Ty(Context); Constant *CU = UndefValue::get(Int32Ty); + Constant *CP = PoisonValue::get(Int32Ty); Constant *C1 = ConstantInt::get(Int32Ty, 1); Constant *C2 = ConstantInt::get(Int32Ty, 2); + Constant *CUU = ConstantVector::get({CU, CU}); + Constant *CPP = ConstantVector::get({CP, CP}); + Constant *CUP = ConstantVector::get({CU, CP}); + EXPECT_EQ(CUU, UndefValue::get(CUU->getType())); + EXPECT_EQ(CPP, PoisonValue::get(CPP->getType())); + EXPECT_NE(CUP, UndefValue::get(CUP->getType())); + Constant *C1211 = ConstantVector::get({C1, C2, C1, C1}); Constant *C12U1 = ConstantVector::get({C1, C2, CU, C1}); Constant *C12U2 = ConstantVector::get({C1, C2, CU, C2}); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 3a60a1f - [InstSimplify] Fold insertelement vec, poison, idx into vec
Author: Juneyoung Lee Date: 2021-01-07T10:10:14+09:00 New Revision: 3a60a1f165708954ce8d279f9692116844a998fa URL: https://github.com/llvm/llvm-project/commit/3a60a1f165708954ce8d279f9692116844a998fa DIFF: https://github.com/llvm/llvm-project/commit/3a60a1f165708954ce8d279f9692116844a998fa.diff LOG: [InstSimplify] Fold insertelement vec, poison, idx into vec This is a simple patch that adds folding from `insertelement vec, poison, idx` into `vec`. Alive2 proof: https://alive2.llvm.org/ce/z/2y2vbC Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93994 Added: Modified: llvm/lib/Analysis/InstructionSimplify.cpp llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll llvm/test/Transforms/InstCombine/extractelement.ll llvm/test/Transforms/InstSimplify/insertelement.ll llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll Removed: diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 5c251452e96d1..96a3ada89db4a 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4401,10 +4401,10 @@ Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx, if (Q.isUndefValue(Idx)) return PoisonValue::get(Vec->getType()); - // If the scalar is undef, and there is no risk of propagating poison from the - // vector value, simplify to the vector value. - if (Q.isUndefValue(Val) && - isGuaranteedNotToBeUndefOrPoison(Vec)) + // If the scalar is poison, or it is undef and there is no risk of + // propagating poison from the vector value, simplify to the vector value. + if (isa(Val) || + (Q.isUndefValue(Val) && isGuaranteedNotToBePoison(Vec))) return Vec; // If we are extracting a value from a vector, then inserting it into the same diff --git a/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll b/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll index f3fad9bb375c1..0792e7aff5168 100644 --- a/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/extractelement-inseltpoison.ll @@ -319,8 +319,7 @@ define <4 x double> @invalid_extractelement(<2 x double> %a, <4 x double> %b, do ; ANY-NEXT:[[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> ; ANY-NEXT:[[E:%.*]] = extractelement <4 x double> [[B]], i32 1 ; ANY-NEXT:store double [[E]], double* [[P:%.*]], align 8 -; ANY-NEXT:[[R:%.*]] = insertelement <4 x double> [[T4]], double poison, i64 0 -; ANY-NEXT:ret <4 x double> [[R]] +; ANY-NEXT:ret <4 x double> [[T4]] ; %t3 = extractelement <2 x double> %a, i32 0 %t4 = insertelement <4 x double> %b, double %t3, i32 2 diff --git a/llvm/test/Transforms/InstCombine/extractelement.ll b/llvm/test/Transforms/InstCombine/extractelement.ll index 7d36618452f5f..4bb2a32681e56 100644 --- a/llvm/test/Transforms/InstCombine/extractelement.ll +++ b/llvm/test/Transforms/InstCombine/extractelement.ll @@ -319,8 +319,7 @@ define <4 x double> @invalid_extractelement(<2 x double> %a, <4 x double> %b, do ; ANY-NEXT:[[T4:%.*]] = shufflevector <4 x double> [[B:%.*]], <4 x double> [[TMP1]], <4 x i32> ; ANY-NEXT:[[E:%.*]] = extractelement <4 x double> [[B]], i32 1 ; ANY-NEXT:store double [[E]], double* [[P:%.*]], align 8 -; ANY-NEXT:[[R:%.*]] = insertelement <4 x double> [[T4]], double poison, i64 0 -; ANY-NEXT:ret <4 x double> [[R]] +; ANY-NEXT:ret <4 x double> [[T4]] ; %t3 = extractelement <2 x double> %a, i32 0 %t4 = insertelement <4 x double> %b, double %t3, i32 2 diff --git a/llvm/test/Transforms/InstSimplify/insertelement.ll b/llvm/test/Transforms/InstSimplify/insertelement.ll index 580670844f22e..8cb3312cf9eb6 100644 --- a/llvm/test/Transforms/InstSimplify/insertelement.ll +++ b/llvm/test/Transforms/InstSimplify/insertelement.ll @@ -52,8 +52,7 @@ define <4 x i32> @test5_poison(<4 x i32> %A) { define <4 x i32> @elem_poison(<4 x i32> %A) { ; CHECK-LABEL: @elem_poison( -; CHECK-NEXT:[[B:%.*]] = insertelement <4 x i32> [[A:%.*]], i32 poison, i32 1 -; CHECK-NEXT:ret <4 x i32> [[B]] +; CHECK-NEXT:ret <4 x i32> [[A:%.*]] ; %B = insertelement <4 x i32> %A, i32 poison, i32 1 ret <4 x i32> %B diff --git a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll index a71379791f20a..176b2a3c49a01 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/alternate-int.ll @@ -425,10 +425,10 @@ define <8 x i32> @sdiv_v8i32_undefs(<8 x i32> %a) { ; CHECK-NEXT:[[AB5:%.*]] = sdiv i32 [[A5]], 4 ; CHECK-NEXT:[[AB6:%.*]] = sdiv i32 [[A6]], 8 ; CHECK-NEXT:[[AB7:%.*]] = sdiv i32 [[A7]], 16 -; CHECK-NEXT:[[TMP1:%.*]] = insertelem
[llvm-branch-commits] [llvm] 9f2d936 - [CodeGen] Update transformations to use poison for shufflevector/insertelem's initial vector elem
Author: Juneyoung Lee Date: 2021-01-10T18:03:51+09:00 New Revision: 9f2d9364b04c4d9651b1ec8612a3968b969fe71d URL: https://github.com/llvm/llvm-project/commit/9f2d9364b04c4d9651b1ec8612a3968b969fe71d DIFF: https://github.com/llvm/llvm-project/commit/9f2d9364b04c4d9651b1ec8612a3968b969fe71d.diff LOG: [CodeGen] Update transformations to use poison for shufflevector/insertelem's initial vector elem This patch is a part of D93817 and makes transformations in CodeGen use poison for shufflevector/insertelem's initial vector element. The change in CodeGenPrepare.cpp is fine because the mask of shufflevector should be always zero. It doesn't touch the second element (which is poison). The change in InterleavedAccessPass.cpp is also fine becauses the mask is of the form where a+km is smaller than the size of the first vector operand. This is guaranteed by the caller of replaceBinOpShuffles, which is lowerInterleavedLoad. It calls isDeInterleaveMask and isDeInterleaveMaskOfFactor to check the mask is the desirable form. isDeInterleaveMask has the check that a+km is smaller than the vector size. To check my understanding, I added an assertion & added a test to show that this optimization doesn't fire in such case. Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D94056 Added: Modified: llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/test/Transforms/InterleavedAccess/X86/interleave-load-extract-shuffle-changes.ll Removed: diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index c621cef8024e..85371d0d5d31 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -6699,6 +6699,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { /// in MVE takes a GPR (integer) register, and the instruction that incorporate /// a VDUP (such as a VADD qd, qm, rm) also require a gpr register. bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) { + // Accept shuf(insertelem(undef/poison, val, 0), undef/poison, <0,0,..>) only if (!match(SVI, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_ZeroInt()), m_Undef(), m_ZeroMask( return false; @@ -6718,9 +6719,7 @@ bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) { Builder.SetInsertPoint(SVI); Value *BC1 = Builder.CreateBitCast( cast(SVI->getOperand(0))->getOperand(1), NewType); - Value *Insert = Builder.CreateInsertElement(UndefValue::get(NewVecType), BC1, - (uint64_t)0); - Value *Shuffle = Builder.CreateShuffleVector(Insert, SVI->getShuffleMask()); + Value *Shuffle = Builder.CreateVectorSplat(NewVecType->getNumElements(), BC1); Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType); SVI->replaceAllUsesWith(BC2); diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp index 6e1621450755..b22e6faeb91c 100644 --- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp +++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp @@ -22,8 +22,8 @@ // // E.g. An interleaved load (Factor = 2): //%wide.vec = load <8 x i32>, <8 x i32>* %ptr -//%v0 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <0, 2, 4, 6> -//%v1 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <1, 3, 5, 7> +//%v0 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <0, 2, 4, 6> +//%v1 = shuffle <8 x i32> %wide.vec, <8 x i32> poison, <1, 3, 5, 7> // // It could be transformed into a ld2 intrinsic in AArch64 backend or a vld2 // intrinsic in ARM backend. @@ -351,6 +351,7 @@ bool InterleavedAccess::lowerInterleavedLoad( Index)) return false; +assert(Shuffle->getShuffleMask().size() <= NumLoadElements); Indices.push_back(Index); } for (auto *Shuffle : BinOpShuffles) { @@ -360,6 +361,8 @@ bool InterleavedAccess::lowerInterleavedLoad( Index)) return false; +assert(Shuffle->getShuffleMask().size() <= NumLoadElements); + if (cast(Shuffle->getOperand(0))->getOperand(0) == LI) Indices.push_back(Index); if (cast(Shuffle->getOperand(0))->getOperand(1) == LI) @@ -394,13 +397,17 @@ bool InterleavedAccess::replaceBinOpShuffles( SmallVectorImpl &Shuffles, LoadInst *LI) { for (auto *SVI : BinOpShuffles) { BinaryOperator *BI = cast(SVI->getOperand(0)); +Type *BIOp0Ty = BI->getOperand(0)->getType(); ArrayRef Mask = SVI->getShuffleMask(); +assert(all_of(Mask, [&](int Idx) { + return Idx < (int)cast(BIOp0Ty)->getNumElements(); +})); -auto *NewSVI1 = new ShuffleVectorInst( -BI->getOperand(0), UndefValue::get(BI->getOperand(0)->getType()), Mask, -SVI->getName(), SVI); +auto *NewSVI1 = +
[llvm-branch-commits] [llvm] 112e3d8 - Add a pre-commit test for D124426
Author: Juneyoung Lee Date: 2022-04-30T20:41:28+09:00 New Revision: 112e3d86870d214bfa27ce18bfa99eb8197e2bc7 URL: https://github.com/llvm/llvm-project/commit/112e3d86870d214bfa27ce18bfa99eb8197e2bc7 DIFF: https://github.com/llvm/llvm-project/commit/112e3d86870d214bfa27ce18bfa99eb8197e2bc7.diff LOG: Add a pre-commit test for D124426 Added: llvm/test/Transforms/InstCombine/select-cmp.ll Modified: Removed: diff --git a/llvm/test/Transforms/InstCombine/select-cmp.ll b/llvm/test/Transforms/InstCombine/select-cmp.ll new file mode 100644 index 0..dd39a78a9029c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/select-cmp.ll @@ -0,0 +1,13 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i1 @f(i1 %cond, i32 %x, i32 %x2) { +; CHECK-LABEL: @f( +; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND:%.*]], i32 poison, i32 [[X:%.*]] +; CHECK-NEXT:[[C:%.*]] = icmp eq i32 [[Y]], [[X2:%.*]] +; CHECK-NEXT:ret i1 [[C]] +; + %y = select i1 %cond, i32 poison, i32 %x + %c = icmp eq i32 %y, %x2 + ret i1 %c +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 40a2e35 - [InstCombine] Remove the undef-related workaround code in visitSelectInst
Author: Juneyoung Lee Date: 2022-04-30T20:48:42+09:00 New Revision: 40a2e35599b5e5fa0dd93ac4edf4bf02ee636f6e URL: https://github.com/llvm/llvm-project/commit/40a2e35599b5e5fa0dd93ac4edf4bf02ee636f6e DIFF: https://github.com/llvm/llvm-project/commit/40a2e35599b5e5fa0dd93ac4edf4bf02ee636f6e.diff LOG: [InstCombine] Remove the undef-related workaround code in visitSelectInst This patch removes an old hack in visitSelectInst that was written to avoid miscompilation bugs in loop unswitch. (Added via https://reviews.llvm.org/D35811) The legacy loop unswitch pass will be removed after D124376, and the new simple loop unswitch pass correctly uses freeze to avoid introducing UB after D124252. Since the hack is not necessary anymore, this patch removes it. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D124426 Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/test/Transforms/InstCombine/select-cmp.ll Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index e1f9c099d79fc..fce9a73d17e7a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2644,22 +2644,6 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { Value *FalseVal = SI.getFalseValue(); Type *SelType = SI.getType(); - // FIXME: Remove this workaround when freeze related patches are done. - // For select with undef operand which feeds into an equality comparison, - // don't simplify it so loop unswitch can know the equality comparison - // may have an undef operand. This is a workaround for PR31652 caused by - // descrepancy about branch on undef between LoopUnswitch and GVN. - if (match(TrueVal, m_Undef()) || match(FalseVal, m_Undef())) { -if (llvm::any_of(SI.users(), [&](User *U) { - ICmpInst *CI = dyn_cast(U); - if (CI && CI->isEquality()) -return true; - return false; -})) { - return nullptr; -} - } - if (Value *V = SimplifySelectInst(CondVal, TrueVal, FalseVal, SQ.getWithInstruction(&SI))) return replaceInstUsesWith(SI, V); diff --git a/llvm/test/Transforms/InstCombine/select-cmp.ll b/llvm/test/Transforms/InstCombine/select-cmp.ll index dd39a78a9029c..2bd4fa9b47156 100644 --- a/llvm/test/Transforms/InstCombine/select-cmp.ll +++ b/llvm/test/Transforms/InstCombine/select-cmp.ll @@ -3,8 +3,7 @@ define i1 @f(i1 %cond, i32 %x, i32 %x2) { ; CHECK-LABEL: @f( -; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND:%.*]], i32 poison, i32 [[X:%.*]] -; CHECK-NEXT:[[C:%.*]] = icmp eq i32 [[Y]], [[X2:%.*]] +; CHECK-NEXT:[[C:%.*]] = icmp eq i32 [[X:%.*]], [[X2:%.*]] ; CHECK-NEXT:ret i1 [[C]] ; %y = select i1 %cond, i32 poison, i32 %x ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 1e785e9 - apply update_test_checks.py to a few files in llvm/test/Transforms/InstCombine
Author: Juneyoung Lee Date: 2020-12-20T01:03:19+09:00 New Revision: 1e785e92624b758e0d0bfe0efe3b4e6d1c44d27c URL: https://github.com/llvm/llvm-project/commit/1e785e92624b758e0d0bfe0efe3b4e6d1c44d27c DIFF: https://github.com/llvm/llvm-project/commit/1e785e92624b758e0d0bfe0efe3b4e6d1c44d27c.diff LOG: apply update_test_checks.py to a few files in llvm/test/Transforms/InstCombine Added: Modified: llvm/test/Transforms/InstCombine/X86/x86-sse4a.ll llvm/test/Transforms/InstCombine/bitcast.ll llvm/test/Transforms/InstCombine/insert-const-shuf.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/X86/x86-sse4a.ll b/llvm/test/Transforms/InstCombine/X86/x86-sse4a.ll index 2ee0c3462c19..541156c0137d 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-sse4a.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-sse4a.ll @@ -7,7 +7,7 @@ define <2 x i64> @test_extrq_call(<2 x i64> %x, <16 x i8> %y) { ; CHECK-LABEL: @test_extrq_call( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) [[ATTR1:#.*]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> %x, <16 x i8> %y) nounwind @@ -150,7 +150,7 @@ define <2 x i64> @test_extrqi_call_constexpr() { define <2 x i64> @test_insertq_call(<2 x i64> %x, <2 x i64> %y) { ; CHECK-LABEL: @test_insertq_call( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertq(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertq(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]]) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = tail call <2 x i64> @llvm.x86.sse4a.insertq(<2 x i64> %x, <2 x i64> %y) nounwind @@ -291,7 +291,7 @@ define <2 x i64> @testUndefinedInsertq_3(<2 x i64> %v, <2 x i64> %i) { define <2 x i64> @test_extrq_arg0(<2 x i64> %x, <16 x i8> %y) { ; CHECK-LABEL: @test_extrq_arg0( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = shufflevector <2 x i64> %x, <2 x i64> undef, <2 x i32> @@ -301,7 +301,7 @@ define <2 x i64> @test_extrq_arg0(<2 x i64> %x, <16 x i8> %y) { define <2 x i64> @test_extrq_arg1(<2 x i64> %x, <16 x i8> %y) { ; CHECK-LABEL: @test_extrq_arg1( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = shufflevector <16 x i8> %y, <16 x i8> undef, <16 x i32> @@ -311,7 +311,7 @@ define <2 x i64> @test_extrq_arg1(<2 x i64> %x, <16 x i8> %y) { define <2 x i64> @test_extrq_args01(<2 x i64> %x, <16 x i8> %y) { ; CHECK-LABEL: @test_extrq_args01( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> [[X:%.*]], <16 x i8> [[Y:%.*]]) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = shufflevector <2 x i64> %x, <2 x i64> undef, <2 x i32> @@ -350,7 +350,7 @@ define <2 x i64> @test_extrqi_ret(<2 x i64> %x) { define <2 x i64> @test_insertq_arg0(<2 x i64> %x, <2 x i64> %y) { ; CHECK-LABEL: @test_insertq_arg0( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertq(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]]) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertq(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]]) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = shufflevector <2 x i64> %x, <2 x i64> undef, <2 x i32> @@ -369,7 +369,7 @@ define <2 x i64> @test_insertq_ret(<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @test_insertqi_arg0(<2 x i64> %x, <2 x i64> %y) { ; CHECK-LABEL: @test_insertqi_arg0( -; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], i8 3, i8 2) #1 +; CHECK-NEXT:[[TMP1:%.*]] = tail call <2 x i64> @llvm.x86.sse4a.insertqi(<2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], i8 3, i8 2) [[ATTR1]] ; CHECK-NEXT:ret <2 x i64> [[TMP1]] ; %1 = shufflevector <2 x i64> %x, <2 x i64> undef, <2 x i32> @@ -379,7 +379,7 @@ define <2 x i64> @test_insertqi_arg0(<2 x i64> %x, <2 x i64> %y) { define <2 x i64> @test_insertqi_arg1(<2 x i64> %x, <2 x i64> %y) { ; CHECK-LABEL: @test_insertqi_arg1( -; CHECK-NEXT:[[TMP1:%.*]] = tail call
[llvm-branch-commits] [llvm] 0d05c1f - [GVN] Add tests for select form of and/or (NFC)
Author: Juneyoung Lee Date: 2020-12-28T03:39:57+09:00 New Revision: 0d05c1f40d691ad492383b6bc2fd7b0703099e07 URL: https://github.com/llvm/llvm-project/commit/0d05c1f40d691ad492383b6bc2fd7b0703099e07 DIFF: https://github.com/llvm/llvm-project/commit/0d05c1f40d691ad492383b6bc2fd7b0703099e07.diff LOG: [GVN] Add tests for select form of and/or (NFC) Added: Modified: llvm/test/Transforms/GVN/condprop.ll Removed: diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll index 1c07ad8441ee..c2b2c9eeaeb0 100644 --- a/llvm/test/Transforms/GVN/condprop.ll +++ b/llvm/test/Transforms/GVN/condprop.ll @@ -79,6 +79,72 @@ nope: ret void } +; CHECK-LABEL: @test3_select( +define void @test3_select(i32 %x, i32 %y) { + %xz = icmp eq i32 %x, 0 + %yz = icmp eq i32 %y, 0 + %z = select i1 %xz, i1 %yz, i1 false + br i1 %z, label %both_zero, label %nope +both_zero: + call void @foo(i1 %xz) +; CHECK: call void @foo(i1 %xz) + call void @foo(i1 %yz) +; CHECK: call void @foo(i1 %yz) + call void @bar(i32 %x) +; CHECK: call void @bar(i32 %x) + call void @bar(i32 %y) +; CHECK: call void @bar(i32 %y) + ret void +nope: + call void @foo(i1 %z) +; CHECK: call void @foo(i1 false) + ret void +} + +; CHECK-LABEL: @test3_or( +define void @test3_or(i32 %x, i32 %y) { + %xz = icmp ne i32 %x, 0 + %yz = icmp ne i32 %y, 0 + %z = or i1 %xz, %yz + br i1 %z, label %nope, label %both_zero +both_zero: + call void @foo(i1 %xz) +; CHECK: call void @foo(i1 false) + call void @foo(i1 %yz) +; CHECK: call void @foo(i1 false) + call void @bar(i32 %x) +; CHECK: call void @bar(i32 0) + call void @bar(i32 %y) +; CHECK: call void @bar(i32 0) + ret void +nope: + call void @foo(i1 %z) +; CHECK: call void @foo(i1 true) + ret void +} + +; CHECK-LABEL: @test3_or_select( +define void @test3_or_select(i32 %x, i32 %y) { + %xz = icmp ne i32 %x, 0 + %yz = icmp ne i32 %y, 0 + %z = select i1 %xz, i1 true, i1 %yz + br i1 %z, label %nope, label %both_zero +both_zero: + call void @foo(i1 %xz) +; CHECK: call void @foo(i1 %xz) + call void @foo(i1 %yz) +; CHECK: call void @foo(i1 %yz) + call void @bar(i32 %x) +; CHECK: call void @bar(i32 %x) + call void @bar(i32 %y) +; CHECK: call void @bar(i32 %y) + ret void +nope: + call void @foo(i1 %z) +; CHECK: call void @foo(i1 true) + ret void +} + ; CHECK-LABEL: @test4( define void @test4(i1 %b, i32 %x) { br i1 %b, label %sw, label %case3 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 0060f10 - [EarlyCSE] Add tests for select form of and/or (NFC)
Author: Juneyoung Lee Date: 2020-12-28T04:19:22+09:00 New Revision: 0060f1013453d4ecaac8b62fb54044285a16a379 URL: https://github.com/llvm/llvm-project/commit/0060f1013453d4ecaac8b62fb54044285a16a379 DIFF: https://github.com/llvm/llvm-project/commit/0060f1013453d4ecaac8b62fb54044285a16a379.diff LOG: [EarlyCSE] Add tests for select form of and/or (NFC) Added: Modified: llvm/test/Transforms/EarlyCSE/and_or.ll Removed: diff --git a/llvm/test/Transforms/EarlyCSE/and_or.ll b/llvm/test/Transforms/EarlyCSE/and_or.ll index b70d0cea3f7f..4a63e28b5ffa 100644 --- a/llvm/test/Transforms/EarlyCSE/and_or.ll +++ b/llvm/test/Transforms/EarlyCSE/and_or.ll @@ -55,6 +55,35 @@ if.false: ret i32 %y } +define i32 @test_02_select(i32 %a, i32 %b, i1 %c) { +; CHECK-LABEL: @test_02_select( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT:[[AND_COND:%.*]] = select i1 [[COND]], i1 [[C:%.*]], i1 false +; CHECK-NEXT:br i1 [[AND_COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[X]] +; CHECK: if.false: +; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[Y]] +; +entry: + %cond = icmp slt i32 %a, %b + %and.cond = select i1 %cond, i1 %c, i1 false + br i1 %and.cond, label %if.true, label %if.false + +if.true: + %cond2 = icmp slt i32 %a, %b + %x = select i1 %cond2, i32 %a, i32 %b + ret i32 %x + +if.false: + %cond3 = icmp slt i32 %a, %b + %y = select i1 %cond3, i32 %a, i32 %b + ret i32 %y +} + define i32 @test_03(i32 %a, i32 %b, i1 %c) { ; CHECK-LABEL: @test_03( ; CHECK-NEXT: entry: @@ -83,6 +112,35 @@ if.false: ret i32 %y } +define i32 @test_03_select(i32 %a, i32 %b, i1 %c) { +; CHECK-LABEL: @test_03_select( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT:[[OR_COND:%.*]] = select i1 [[COND]], i1 true, i1 [[C:%.*]] +; CHECK-NEXT:br i1 [[OR_COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[X]] +; CHECK: if.false: +; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[Y]] +; +entry: + %cond = icmp slt i32 %a, %b + %or.cond = select i1 %cond, i1 true, i1 %c + br i1 %or.cond, label %if.true, label %if.false + +if.true: + %cond2 = icmp slt i32 %a, %b + %x = select i1 %cond2, i32 %a, i32 %b + ret i32 %x + +if.false: + %cond3 = icmp slt i32 %a, %b + %y = select i1 %cond3, i32 %a, i32 %b + ret i32 %y +} + define i32 @test_04(i32 %a, i32 %b, i1 %c1, i1 %c2) { ; CHECK-LABEL: @test_04( ; CHECK-NEXT: entry: @@ -113,6 +171,37 @@ if.false: ret i32 %y } +define i32 @test_04_select(i32 %a, i32 %b, i1 %c1, i1 %c2) { +; CHECK-LABEL: @test_04_select( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT:[[AND_COND1:%.*]] = select i1 [[COND]], i1 [[C1:%.*]], i1 false +; CHECK-NEXT:[[AND_COND2:%.*]] = select i1 [[AND_COND1]], i1 [[C2:%.*]], i1 false +; CHECK-NEXT:br i1 [[AND_COND2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[X]] +; CHECK: if.false: +; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[Y]] +; +entry: + %cond = icmp slt i32 %a, %b + %and.cond1 = select i1 %cond, i1 %c1, i1 false + %and.cond2 = select i1 %and.cond1, i1 %c2, i1 false + br i1 %and.cond2, label %if.true, label %if.false + +if.true: + %cond2 = icmp slt i32 %a, %b + %x = select i1 %cond2, i32 %a, i32 %b + ret i32 %x + +if.false: + %cond3 = icmp slt i32 %a, %b + %y = select i1 %cond3, i32 %a, i32 %b + ret i32 %y +} + define i32 @test_05(i32 %a, i32 %b, i1 %c1, i1 %c2) { ; CHECK-LABEL: @test_05( ; CHECK-NEXT: entry: @@ -142,3 +231,34 @@ if.false: %y = select i1 %cond3, i32 %a, i32 %b ret i32 %y } + +define i32 @test_05_select(i32 %a, i32 %b, i1 %c1, i1 %c2) { +; CHECK-LABEL: @test_05_select( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT:[[OR_COND1:%.*]] = select i1 [[COND]], i1 true, i1 [[C1:%.*]] +; CHECK-NEXT:[[OR_COND2:%.*]] = select i1 [[OR_COND1]], i1 true, i1 [[C2:%.*]] +; CHECK-NEXT:br i1 [[OR_COND2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[X]] +; CHECK: if.false: +; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] +; CHECK-NEXT:ret i32 [[Y]] +; +entry: + %cond = icm
[llvm-branch-commits] [llvm] f1d648b - [GVN] Use m_LogicalAnd/Or to propagate equality from branch conditions
Author: Juneyoung Lee Date: 2020-12-28T05:28:38+09:00 New Revision: f1d648b973d32ab0e70ef20efb0f146240e50f58 URL: https://github.com/llvm/llvm-project/commit/f1d648b973d32ab0e70ef20efb0f146240e50f58 DIFF: https://github.com/llvm/llvm-project/commit/f1d648b973d32ab0e70ef20efb0f146240e50f58.diff LOG: [GVN] Use m_LogicalAnd/Or to propagate equality from branch conditions This patch makes GVN recognize `select c1, c2, false` as well as `select c1, true, c2` branch condition and propagate equality from these. See llvm.org/pr48353, D93065 Differential Revision: https://reviews.llvm.org/D93841 Added: Modified: llvm/lib/Transforms/Scalar/GVN.cpp llvm/test/Transforms/GVN/condprop.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 32b38fd97f31..5d37eb73f9b1 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2087,8 +2087,8 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root, // If "A && B" is known true then both A and B are known true. If "A || B" // is known false then both A and B are known false. Value *A, *B; -if ((isKnownTrue && match(LHS, m_And(m_Value(A), m_Value(B || -(isKnownFalse && match(LHS, m_Or(m_Value(A), m_Value(B) { +if ((isKnownTrue && match(LHS, m_LogicalAnd(m_Value(A), m_Value(B || +(isKnownFalse && match(LHS, m_LogicalOr(m_Value(A), m_Value(B) { Worklist.push_back(std::make_pair(A, RHS)); Worklist.push_back(std::make_pair(B, RHS)); continue; diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll index c2b2c9eeaeb0..bb7befce9e82 100644 --- a/llvm/test/Transforms/GVN/condprop.ll +++ b/llvm/test/Transforms/GVN/condprop.ll @@ -87,13 +87,13 @@ define void @test3_select(i32 %x, i32 %y) { br i1 %z, label %both_zero, label %nope both_zero: call void @foo(i1 %xz) -; CHECK: call void @foo(i1 %xz) +; CHECK: call void @foo(i1 true) call void @foo(i1 %yz) -; CHECK: call void @foo(i1 %yz) +; CHECK: call void @foo(i1 true) call void @bar(i32 %x) -; CHECK: call void @bar(i32 %x) +; CHECK: call void @bar(i32 0) call void @bar(i32 %y) -; CHECK: call void @bar(i32 %y) +; CHECK: call void @bar(i32 0) ret void nope: call void @foo(i1 %z) @@ -131,13 +131,13 @@ define void @test3_or_select(i32 %x, i32 %y) { br i1 %z, label %nope, label %both_zero both_zero: call void @foo(i1 %xz) -; CHECK: call void @foo(i1 %xz) +; CHECK: call void @foo(i1 false) call void @foo(i1 %yz) -; CHECK: call void @foo(i1 %yz) +; CHECK: call void @foo(i1 false) call void @bar(i32 %x) -; CHECK: call void @bar(i32 %x) +; CHECK: call void @bar(i32 0) call void @bar(i32 %y) -; CHECK: call void @bar(i32 %y) +; CHECK: call void @bar(i32 0) ret void nope: call void @foo(i1 %z) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] d3f1f7b - [EarlyCSE] Use m_LogicalAnd/Or matchers to handle branch conditions
Author: Juneyoung Lee Date: 2020-12-28T05:36:26+09:00 New Revision: d3f1f7b6bca585b76d40422e8076d59113e3bb80 URL: https://github.com/llvm/llvm-project/commit/d3f1f7b6bca585b76d40422e8076d59113e3bb80 DIFF: https://github.com/llvm/llvm-project/commit/d3f1f7b6bca585b76d40422e8076d59113e3bb80.diff LOG: [EarlyCSE] Use m_LogicalAnd/Or matchers to handle branch conditions EarlyCSE's handleBranchCondition says: ``` // If the condition is AND operation, we can propagate its operands into the // true branch. If it is OR operation, we can propagate them into the false // branch. ``` This holds for the corresponding select patterns as well. This is a part of an ongoing work for disabling buggy select->and/or transformations. See llvm.org/pr48353 and D93065 for more context Proof: and: https://alive2.llvm.org/ce/z/MQWodU or: https://alive2.llvm.org/ce/z/9GLbB_ Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93842 Added: Modified: llvm/lib/Transforms/Scalar/EarlyCSE.cpp llvm/test/Transforms/EarlyCSE/and_or.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index be2860960500..f005f69519f7 100644 --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -1033,9 +1033,14 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst, auto *TorF = (BI->getSuccessor(0) == BB) ? ConstantInt::getTrue(BB->getContext()) : ConstantInt::getFalse(BB->getContext()); - auto MatchBinOp = [](Instruction *I, unsigned Opcode) { -if (BinaryOperator *BOp = dyn_cast(I)) - return BOp->getOpcode() == Opcode; + auto MatchBinOp = [](Instruction *I, unsigned Opcode, Value *&LHS, + Value *&RHS) { +if (Opcode == Instruction::And && +match(I, m_LogicalAnd(m_Value(LHS), m_Value(RHS + return true; +else if (Opcode == Instruction::Or && + match(I, m_LogicalOr(m_Value(LHS), m_Value(RHS + return true; return false; }; // If the condition is AND operation, we can propagate its operands into the @@ -1066,8 +1071,9 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst, } } -if (MatchBinOp(Curr, PropagateOpcode)) - for (auto &Op : cast(Curr)->operands()) +Value *LHS, *RHS; +if (MatchBinOp(Curr, PropagateOpcode, LHS, RHS)) + for (auto &Op : { LHS, RHS }) if (Instruction *OPI = dyn_cast(Op)) if (SimpleValue::canHandle(OPI) && Visited.insert(OPI).second) WorkList.push_back(OPI); diff --git a/llvm/test/Transforms/EarlyCSE/and_or.ll b/llvm/test/Transforms/EarlyCSE/and_or.ll index 4a63e28b5ffa..2c04e7e3cf90 100644 --- a/llvm/test/Transforms/EarlyCSE/and_or.ll +++ b/llvm/test/Transforms/EarlyCSE/and_or.ll @@ -62,8 +62,7 @@ define i32 @test_02_select(i32 %a, i32 %b, i1 %c) { ; CHECK-NEXT:[[AND_COND:%.*]] = select i1 [[COND]], i1 [[C:%.*]], i1 false ; CHECK-NEXT:br i1 [[AND_COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: -; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] -; CHECK-NEXT:ret i32 [[X]] +; CHECK-NEXT:ret i32 [[A]] ; CHECK: if.false: ; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] ; CHECK-NEXT:ret i32 [[Y]] @@ -122,8 +121,7 @@ define i32 @test_03_select(i32 %a, i32 %b, i1 %c) { ; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] ; CHECK-NEXT:ret i32 [[X]] ; CHECK: if.false: -; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] -; CHECK-NEXT:ret i32 [[Y]] +; CHECK-NEXT:ret i32 [[B]] ; entry: %cond = icmp slt i32 %a, %b @@ -179,8 +177,7 @@ define i32 @test_04_select(i32 %a, i32 %b, i1 %c1, i1 %c2) { ; CHECK-NEXT:[[AND_COND2:%.*]] = select i1 [[AND_COND1]], i1 [[C2:%.*]], i1 false ; CHECK-NEXT:br i1 [[AND_COND2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: -; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] -; CHECK-NEXT:ret i32 [[X]] +; CHECK-NEXT:ret i32 [[A]] ; CHECK: if.false: ; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] ; CHECK-NEXT:ret i32 [[Y]] @@ -243,8 +240,7 @@ define i32 @test_05_select(i32 %a, i32 %b, i1 %c1, i1 %c2) { ; CHECK-NEXT:[[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] ; CHECK-NEXT:ret i32 [[X]] ; CHECK: if.false: -; CHECK-NEXT:[[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] -; CHECK-NEXT:ret i32 [[Y]] +; CHECK-NEXT:ret i32 [[B]] ; entry: %cond = icmp slt i32 %a, %b ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] eca40c3 - [ValueTracking] Add unit tests for isKnownNonZero, isImpliedCondition (NFC)
Author: Juneyoung Lee Date: 2020-12-28T06:32:57+09:00 New Revision: eca40c36ef1c02877d957e12135faec12a5b3c26 URL: https://github.com/llvm/llvm-project/commit/eca40c36ef1c02877d957e12135faec12a5b3c26 DIFF: https://github.com/llvm/llvm-project/commit/eca40c36ef1c02877d957e12135faec12a5b3c26.diff LOG: [ValueTracking] Add unit tests for isKnownNonZero, isImpliedCondition (NFC) Added: Modified: llvm/unittests/Analysis/ValueTrackingTest.cpp Removed: diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 721a342040ba..e9d53efbf76f 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -67,6 +67,9 @@ class ValueTrackingTest : public testing::Test { A = findInstructionByNameOrNull(F, "A"); ASSERT_TRUE(A) << "@test must have an instruction %A"; +A2 = findInstructionByNameOrNull(F, "A2"); +A3 = findInstructionByNameOrNull(F, "A3"); +A4 = findInstructionByNameOrNull(F, "A4"); CxtI = findInstructionByNameOrNull(F, "CxtI"); CxtI2 = findInstructionByNameOrNull(F, "CxtI2"); @@ -77,6 +80,8 @@ class ValueTrackingTest : public testing::Test { std::unique_ptr M; Function *F = nullptr; Instruction *A = nullptr; + // Instructions (optional) + Instruction *A2 = nullptr, *A3 = nullptr, *A4 = nullptr; // Context instructions (optional) Instruction *CxtI = nullptr, *CxtI2 = nullptr, *CxtI3 = nullptr; @@ -1004,6 +1009,68 @@ TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { expectKnownBits(/*zero*/ 95u, /*one*/ 32u); } +TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) { + parseAssembly(R"( +declare i8* @f_i8() +define void @test(i1 %c) { + %A = call i8* @f_i8() + %B = call i8* @f_i8() + %c1 = icmp ne i8* %A, null + %cond = and i1 %c1, %c + br i1 %cond, label %T, label %Q +T: + %CxtI = add i32 0, 0 + ret void +Q: + %CxtI2 = add i32 0, 0 + ret void +} + )"); + AssumptionCache AC(*F); + DominatorTree DT(*F); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI, &DT), true); + EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI2, &DT), false); +} + +TEST_F(ValueTrackingTest, IsImpliedConditionAnd) { + parseAssembly(R"( +define void @test(i32 %x, i32 %y) { + %c1 = icmp ult i32 %x, 10 + %c2 = icmp ult i32 %y, 15 + %A = and i1 %c1, %c2 + ; x < 10 /\ y < 15 + %A2 = icmp ult i32 %x, 20 + %A3 = icmp uge i32 %y, 20 + %A4 = icmp ult i32 %x, 5 + ret void +} + )"); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isImpliedCondition(A, A2, DL), true); + EXPECT_EQ(isImpliedCondition(A, A3, DL), false); + EXPECT_EQ(isImpliedCondition(A, A4, DL), None); +} + +TEST_F(ValueTrackingTest, IsImpliedConditionOr) { + parseAssembly(R"( +define void @test(i32 %x, i32 %y) { + %c1 = icmp ult i32 %x, 10 + %c2 = icmp ult i32 %y, 15 + %A = or i1 %c1, %c2 ; negated + ; x >= 10 /\ y >= 15 + %A2 = icmp ult i32 %x, 5 + %A3 = icmp uge i32 %y, 10 + %A4 = icmp ult i32 %x, 15 + ret void +} + )"); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false); + EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true); + EXPECT_EQ(isImpliedCondition(A, A4, DL, false), None); +} + TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) { // %q is known nonzero without known bits. // Because %q is nonzero, %A[0] is known to be zero. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 860199d - [ValueTracking] Use m_LogicalAnd/Or to look into conditions
Author: Juneyoung Lee Date: 2020-12-28T08:32:45+09:00 New Revision: 860199dfbe60d78a7da6406622b635a2d4435db3 URL: https://github.com/llvm/llvm-project/commit/860199dfbe60d78a7da6406622b635a2d4435db3 DIFF: https://github.com/llvm/llvm-project/commit/860199dfbe60d78a7da6406622b635a2d4435db3.diff LOG: [ValueTracking] Use m_LogicalAnd/Or to look into conditions This patch updates isImpliedCondition/isKnownNonZero to look into select form of and/or as well. See llvm.org/pr48353 and D93065 for more context Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D93845 Added: Modified: llvm/lib/Analysis/ValueTracking.cpp llvm/unittests/Analysis/ValueTrackingTest.cpp Removed: diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 29091806cff3..25f6be2b10dd 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2131,13 +2131,12 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V, // correct to assume that all conditions of AND are met in true branch. // TODO: Support similar logic of OR and EQ predicate? if (NonNullIfTrue) - if (auto *BO = dyn_cast(Curr)) -if (BO->getOpcode() == Instruction::And) { - for (auto *BOU : BO->users()) -if (Visited.insert(BOU).second) - WorkList.push_back(BOU); - continue; -} + if (match(Curr, m_LogicalAnd(m_Value(), m_Value( { +for (auto *CurrU : Curr->users()) + if (Visited.insert(CurrU).second) +WorkList.push_back(CurrU); +continue; + } if (const BranchInst *BI = dyn_cast(Curr)) { assert(BI->isConditional() && "uses a comparison!"); @@ -6156,25 +6155,25 @@ static Optional isImpliedCondICmps(const ICmpInst *LHS, /// Return true if LHS implies RHS is true. Return false if LHS implies RHS is /// false. Otherwise, return None if we can't infer anything. We expect the -/// RHS to be an icmp and the LHS to be an 'and' or an 'or' instruction. +/// RHS to be an icmp and the LHS to be an 'and', 'or', or a 'select' instruction. static Optional -isImpliedCondAndOr(const BinaryOperator *LHS, CmpInst::Predicate RHSPred, +isImpliedCondAndOr(const Instruction *LHS, CmpInst::Predicate RHSPred, const Value *RHSOp0, const Value *RHSOp1, - const DataLayout &DL, bool LHSIsTrue, unsigned Depth) { - // The LHS must be an 'or' or an 'and' instruction. + // The LHS must be an 'or', 'and', or a 'select' instruction. assert((LHS->getOpcode() == Instruction::And || - LHS->getOpcode() == Instruction::Or) && - "Expected LHS to be 'and' or 'or'."); + LHS->getOpcode() == Instruction::Or || + LHS->getOpcode() == Instruction::Select) && + "Expected LHS to be 'and', 'or', or 'select'."); assert(Depth <= MaxAnalysisRecursionDepth && "Hit recursion limit"); // If the result of an 'or' is false, then we know both legs of the 'or' are // false. Similarly, if the result of an 'and' is true, then we know both // legs of the 'and' are true. - Value *ALHS, *ARHS; - if ((!LHSIsTrue && match(LHS, m_Or(m_Value(ALHS), m_Value(ARHS || - (LHSIsTrue && match(LHS, m_And(m_Value(ALHS), m_Value(ARHS) { + const Value *ALHS, *ARHS; + if ((!LHSIsTrue && match(LHS, m_LogicalOr(m_Value(ALHS), m_Value(ARHS || + (LHSIsTrue && match(LHS, m_LogicalAnd(m_Value(ALHS), m_Value(ARHS) { // FIXME: Make this non-recursion. if (Optional Implication = isImpliedCondition( ALHS, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue, Depth + 1)) @@ -6215,13 +6214,14 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred, return isImpliedCondICmps(LHSCmp, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue, Depth); - /// The LHS should be an 'or' or an 'and' instruction. We expect the RHS to - /// be / an icmp. FIXME: Add support for and/or on the RHS. - const BinaryOperator *LHSBO = dyn_cast(LHS); - if (LHSBO) { -if ((LHSBO->getOpcode() == Instruction::And || - LHSBO->getOpcode() == Instruction::Or)) - return isImpliedCondAndOr(LHSBO, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue, + /// The LHS should be an 'or', 'and', or a 'select' instruction. We expect + /// the RHS to be an icmp. + /// FIXME: Add support for and/or/select on the RHS. + if (const Instruction *LHSI = dyn_cast(LHS)) { +if ((LHSI->getOpcode() == Instruction::And || + LHSI->getOpcode() == Instruction::Or || + LHSI->getOpcode() == Instruction::Select)) + return isImpliedCondAndOr(LHSI, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue, Depth); } return None; diff --git a/llvm/unittests/Analys
[llvm-branch-commits] [llvm] e7e6335 - ReleaseNotes: Add updates in LangRef related with undef/poison
Author: Juneyoung Lee Date: 2020-09-08T11:40:24+09:00 New Revision: e7e6335763cafe06988a6c06ed50af0b4ec28d8b URL: https://github.com/llvm/llvm-project/commit/e7e6335763cafe06988a6c06ed50af0b4ec28d8b DIFF: https://github.com/llvm/llvm-project/commit/e7e6335763cafe06988a6c06ed50af0b4ec28d8b.diff LOG: ReleaseNotes: Add updates in LangRef related with undef/poison Added: Modified: llvm/docs/ReleaseNotes.rst Removed: diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index cbc8c0859c7b..0d5e0137bbc4 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -101,6 +101,18 @@ Changes to the LLVM IR where ``uint64_t`` was used to denote the size in bits of a IR type we have partially migrated the codebase to using ``llvm::TypeSize``. +* Branching on ``undef``/``poison`` is undefined behavior. It is needed for + correctly analyzing value ranges based on branch conditions. This is + consistent with MSan's behavior as well. + +* ``memset``/``memcpy``/``memmove`` can take ``undef``/``poison`` pointer(s) + if the size to fill is zero. + +* Passing ``undef``/``poison`` to a standard I/O library function call + (`printf`/`fputc`/...) is undefined behavior. The new ``noundef`` attribute + is attached to the functions' arguments. The full list is available at + ``llvm::inferLibFuncAttributes``. + Changes to building LLVM @@ -305,6 +317,10 @@ Changes to the Go bindings Changes to the DAG infrastructure - +* A SelDag-level freeze instruction has landed. It is simply lowered as a copy + operation to MachineIR, but to make it fully correct either IMPLICIT_DEF + should be fixed or the equivalent FREEZE operation should be added to + MachineIR. Changes to the Debug Info - ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 2e32c49 - [LangRef] Add poison constant
Author: Juneyoung Lee Date: 2020-11-27T10:29:52+09:00 New Revision: 2e32c49d974fdacf8fb598c99782cd7256478a28 URL: https://github.com/llvm/llvm-project/commit/2e32c49d974fdacf8fb598c99782cd7256478a28 DIFF: https://github.com/llvm/llvm-project/commit/2e32c49d974fdacf8fb598c99782cd7256478a28.diff LOG: [LangRef] Add poison constant This patch adds a description about the newly added poison constant to LangRef. Differential Revision: https://reviews.llvm.org/D92162 Added: Modified: llvm/docs/LangRef.rst Removed: diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 47f24e9aa9f7..2cd3f93cffef 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3657,13 +3657,13 @@ input IR as well. Poison Values - +A poison value is a result of an erroneous operation. In order to facilitate speculative execution, many instructions do not invoke immediate undefined behavior when provided with illegal operands, and return a poison value instead. - -There is currently no way of representing a poison value in the IR; they -only exist when produced by operations such as :ref:`add ` with -the ``nsw`` flag. +The string '``poison``' can be used anywhere a constant is expected, and +operations such as :ref:`add ` with the ``nsw`` flag can produce +a poison value. Poison value behavior is defined in terms of value *dependence*: @@ -3732,13 +3732,14 @@ Here are some examples: entry: %poison = sub nuw i32 0, 1 ; Results in a poison value. + %poison2 = sub i32 poison, 1 ; Also results in a poison value. %still_poison = and i32 %poison, 0 ; 0, but also poison. %poison_yet_again = getelementptr i32, i32* @h, i32 %still_poison store i32 0, i32* %poison_yet_again ; Undefined behavior due to ; store to poison. store i32 %poison, i32* @g ; Poison value stored to memory. - %poison2 = load i32, i32* @g ; Poison value loaded back from memory. + %poison3 = load i32, i32* @g ; Poison value loaded back from memory. %narrowaddr = bitcast i32* @g to i16* %wideaddr = bitcast i32* @g to i64* ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c6b62ef - [ConstantFold] Fold operations to poison if possible
Author: Juneyoung Lee Date: 2020-11-29T02:28:40+09:00 New Revision: c6b62efb9103466b6cefca1bd99a5b04b4ced044 URL: https://github.com/llvm/llvm-project/commit/c6b62efb9103466b6cefca1bd99a5b04b4ced044 DIFF: https://github.com/llvm/llvm-project/commit/c6b62efb9103466b6cefca1bd99a5b04b4ced044.diff LOG: [ConstantFold] Fold operations to poison if possible This patch updates ConstantFold, so operations are folded into poison if possible. casts: https://alive2.llvm.org/ce/z/WSj7rw binary operations (arithmetic): https://alive2.llvm.org/ce/z/_7dEyJ binary operations (bitwise): https://alive2.llvm.org/ce/z/cezjVN vector/aggregate operations: https://alive2.llvm.org/ce/z/BQ7hWz unary ops: https://alive2.llvm.org/ce/z/yBRs4q other ops: https://alive2.llvm.org/ce/z/iXbcFD Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D92203 Added: llvm/test/Transforms/InstSimplify/ConstProp/poison.ll Modified: llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/test/Transforms/InstSimplify/ConstProp/InsertElement.ll llvm/unittests/IR/ConstantsTest.cpp Removed: diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index b8502673a829..a52cd725d530 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -522,6 +522,9 @@ static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo, Type *DestTy, Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, Type *DestTy) { + if (isa(V)) +return PoisonValue::get(DestTy); + if (isa(V)) { // zext(undef) = 0, because the top bits will be zero. // sext(undef) = 0, because the top bits will all be the same. @@ -759,7 +762,9 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, Constant *V2Element = ConstantExpr::getExtractElement(V2, ConstantInt::get(Ty, i)); auto *Cond = cast(CondV->getOperand(i)); - if (V1Element == V2Element) { + if (isa(Cond)) { +V = PoisonValue::get(V1Element->getType()); + } else if (V1Element == V2Element) { V = V1Element; } else if (isa(Cond)) { V = isa(V1Element) ? V1Element : V2Element; @@ -775,6 +780,9 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, return ConstantVector::get(Result); } + if (isa(Cond)) +return PoisonValue::get(V1->getType()); + if (isa(Cond)) { if (isa(V1)) return V1; return V2; @@ -782,9 +790,17 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (V1 == V2) return V1; + if (isa(V1)) +return V2; + if (isa(V2)) +return V1; + // If the true or false value is undef, we can fold to the other value as // long as the other value isn't poison. auto NotPoison = [](Constant *C) { +if (isa(C)) + return false; + // TODO: We can analyze ConstExpr by opcode to determine if there is any // possibility of poison. if (isa(C)) @@ -821,9 +837,13 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx) { auto *ValVTy = cast(Val->getType()); + // extractelt poison, C -> poison + // extractelt C, undef -> poison + if (isa(Val) || isa(Idx)) +return PoisonValue::get(ValVTy->getElementType()); + // extractelt undef, C -> undef - // extractelt C, undef -> undef - if (isa(Val) || isa(Idx)) + if (isa(Val)) return UndefValue::get(ValVTy->getElementType()); auto *CIdx = dyn_cast(Idx); @@ -831,9 +851,9 @@ Constant *llvm::ConstantFoldExtractElementInstruction(Constant *Val, return nullptr; if (auto *ValFVTy = dyn_cast(Val->getType())) { -// ee({w,x,y,z}, wrong_value) -> undef +// ee({w,x,y,z}, wrong_value) -> poison if (CIdx->uge(ValFVTy->getNumElements())) - return UndefValue::get(ValFVTy->getElementType()); + return PoisonValue::get(ValFVTy->getElementType()); } // ee (gep (ptr, idx0, ...), idx) -> gep (ee (ptr, idx), ee (idx0, idx), ...) @@ -882,7 +902,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt, Constant *Idx) { if (isa(Idx)) -return UndefValue::get(Val->getType()); +return PoisonValue::get(Val->getType()); ConstantInt *CIdx = dyn_cast(Idx); if (!CIdx) return nullptr; @@ -1084,6 +1104,10 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, return C1; } + // Binary operations propagate poison. + if (isa(C1) || isa(C2)) +return PoisonValue::get(C1->getType()); + // Handle scalar UndefValue and scalable vector UndefValue. Fixed-length // vectors are always evaluated per element. bool IsScala
[llvm-branch-commits] [llvm] 1856e22 - [LangRef] minor fixes to poison examples and well-defined values section (NFC)
Author: Juneyoung Lee Date: 2020-11-29T20:51:25+09:00 New Revision: 1856e22eeb2de6e6d4325e3eed1e718abd89ea4b URL: https://github.com/llvm/llvm-project/commit/1856e22eeb2de6e6d4325e3eed1e718abd89ea4b DIFF: https://github.com/llvm/llvm-project/commit/1856e22eeb2de6e6d4325e3eed1e718abd89ea4b.diff LOG: [LangRef] minor fixes to poison examples and well-defined values section (NFC) Added: Modified: llvm/docs/LangRef.rst Removed: diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 2cd3f93cffef..e359fc730515 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3743,8 +3743,8 @@ Here are some examples: %narrowaddr = bitcast i32* @g to i16* %wideaddr = bitcast i32* @g to i64* - %poison3 = load i16, i16* %narrowaddr ; Returns a poison value. - %poison4 = load i64, i64* %wideaddr ; Returns a poison value. + %poison4 = load i16, i16* %narrowaddr ; Returns a poison value. + %poison5 = load i64, i64* %wideaddr ; Returns a poison value. %cmp = icmp slt i32 %poison, 0 ; Returns a poison value. br i1 %cmp, label %end, label %end ; undefined behavior @@ -3763,8 +3763,7 @@ The padding of an aggregate isn't considered, since it isn't visible without storing it into memory and loading it with a diff erent type. A constant of a :ref:`single value `, non-vector type is well -defined if it is a non-undef constant. Note that there is no poison constant -in LLVM. +defined if it is neither '``undef``' constant nor '``poison``' constant. The result of :ref:`freeze instruction ` is well defined regardless of its operand. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 53040a9 - [ConstantFold] Fold more operations to poison
Author: Juneyoung Lee Date: 2020-11-29T21:19:48+09:00 New Revision: 53040a968dc2ff20931661e55f05da2ef8b964a0 URL: https://github.com/llvm/llvm-project/commit/53040a968dc2ff20931661e55f05da2ef8b964a0 DIFF: https://github.com/llvm/llvm-project/commit/53040a968dc2ff20931661e55f05da2ef8b964a0.diff LOG: [ConstantFold] Fold more operations to poison This patch folds more operations to poison. Alive2 proof: https://alive2.llvm.org/ce/z/mxcb9G (it does not contain tests about div/rem because they fold to poison when raising UB) Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D92270 Added: Modified: clang/test/Frontend/fixed_point_unary.c llvm/lib/IR/ConstantFold.cpp llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-fold-binop-select.ll llvm/test/Transforms/InstCombine/apint-shift.ll llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll llvm/test/Transforms/InstCombine/canonicalize-shl-lshr-to-masking.ll llvm/test/Transforms/InstCombine/icmp.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-a.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-c.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-e.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-a.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-c.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-e.ll llvm/test/Transforms/InstCombine/select-of-bittest.ll llvm/test/Transforms/InstCombine/shift-add.ll llvm/test/Transforms/InstSimplify/ConstProp/InsertElement.ll llvm/test/Transforms/InstSimplify/ConstProp/cast.ll llvm/test/Transforms/InstSimplify/ConstProp/poison.ll llvm/test/Transforms/InstSimplify/ConstProp/shift.ll llvm/test/Transforms/InstSimplify/ConstProp/vector-undef-elts.ll llvm/test/Transforms/InstSimplify/ConstProp/vscale.ll llvm/test/Transforms/InstSimplify/div.ll llvm/test/Transforms/InstSimplify/rem.ll llvm/test/Transforms/InstSimplify/undef.ll llvm/test/Transforms/SROA/phi-gep.ll llvm/test/Transforms/SROA/select-gep.ll llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll llvm/test/Transforms/VectorCombine/X86/insert-binop.ll llvm/unittests/IR/ConstantsTest.cpp Removed: diff --git a/clang/test/Frontend/fixed_point_unary.c b/clang/test/Frontend/fixed_point_unary.c index 849e38a94bc4..6ce760daba11 100644 --- a/clang/test/Frontend/fixed_point_unary.c +++ b/clang/test/Frontend/fixed_point_unary.c @@ -90,7 +90,7 @@ void inc_usa() { // SIGNED-LABEL: @inc_uf( // SIGNED-NEXT: entry: // SIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @uf, align 2 -// SIGNED-NEXT:[[TMP1:%.*]] = add i16 [[TMP0]], undef +// SIGNED-NEXT:[[TMP1:%.*]] = add i16 [[TMP0]], poison // SIGNED-NEXT:store i16 [[TMP1]], i16* @uf, align 2 // SIGNED-NEXT:ret void // @@ -271,7 +271,7 @@ void dec_usa() { // SIGNED-LABEL: @dec_uf( // SIGNED-NEXT: entry: // SIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @uf, align 2 -// SIGNED-NEXT:[[TMP1:%.*]] = sub i16 [[TMP0]], undef +// SIGNED-NEXT:[[TMP1:%.*]] = sub i16 [[TMP0]], poison // SIGNED-NEXT:store i16 [[TMP1]], i16* @uf, align 2 // SIGNED-NEXT:ret void // diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index a52cd725d530..3243ddd604ee 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -630,7 +630,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored)) { // Undefined behavior invoked - the destination type can't represent // the input constant. -return UndefValue::get(DestTy); +return PoisonValue::get(DestTy); } return ConstantInt::get(FPC->getContext(), IntVal); } @@ -916,7 +916,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, unsigned NumElts = ValTy->getNumElements(); if (CIdx->uge(NumElts)) -return UndefValue::get(Val->getType()); +return PoisonValue::get(Val->getType()); SmallVector Result; Result.reserve(NumElts); @@ -1144,23 +1144,21
[llvm-branch-commits] [llvm] 9c49dcc - [ConstantFold] Don't fold and/or i1 poison to poison (NFC)
Author: Juneyoung Lee Date: 2020-11-30T22:58:31+09:00 New Revision: 9c49dcc356eb4c59fc1353bbbaae6d3a56a656c1 URL: https://github.com/llvm/llvm-project/commit/9c49dcc356eb4c59fc1353bbbaae6d3a56a656c1 DIFF: https://github.com/llvm/llvm-project/commit/9c49dcc356eb4c59fc1353bbbaae6d3a56a656c1.diff LOG: [ConstantFold] Don't fold and/or i1 poison to poison (NFC) .. because it causes miscompilation when combined with select i1 -> and/or. It is the select fold which is incorrect; but it is costly to disable the fold, so hack this one. D92270 Added: Modified: llvm/lib/IR/ConstantFold.cpp llvm/test/Transforms/InstSimplify/ConstProp/poison.ll Removed: diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 3243ddd604ee..d9564a31b5de 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1105,7 +1105,14 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, } // Binary operations propagate poison. - if (isa(C1) || isa(C2)) + // FIXME: Currently, or/and i1 poison aren't folded into poison because + // it causes miscompilation when combined with another optimization in + // InstCombine (select i1 -> and/or). The select fold is wrong, but + // fixing it requires an effort, so temporarily disable this until it is + // fixed. + bool PoisonFold = !C1->getType()->isIntegerTy(1) || +(Opcode != Instruction::Or && Opcode != Instruction::And); + if (PoisonFold && (isa(C1) || isa(C2))) return PoisonValue::get(C1->getType()); // Handle scalar UndefValue and scalable vector UndefValue. Fixed-length diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/poison.ll b/llvm/test/Transforms/InstSimplify/ConstProp/poison.ll index 542823a44e2f..f3fe29ff57ba 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/poison.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/poison.ll @@ -114,3 +114,15 @@ define void @other_ops(i8 %x) { call void (...) @use(i1 %i1, i1 %i2, i8 %i3, i8 %i4, i8* getelementptr (i8, i8* poison, i64 1), i8* getelementptr inbounds (i8, i8* undef, i64 1)) ret void } + +; TODO: these must be folded into poison; D92270 +define void @logicalops_i1(i1 %x) { +; CHECK-LABEL: @logicalops_i1( +; CHECK-NEXT:call void (...) @use(i1 true, i1 false) +; CHECK-NEXT:ret void +; + %i1 = or i1 %x, poison + %i2 = and i1 %x, poison + call void (...) @use(i1 %i1, i1 %i2) + ret void +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 8e50461 - [LangRef] missing link, minor fix
Author: Juneyoung Lee Date: 2020-11-30T23:09:36+09:00 New Revision: 8e504615e9f1b27c06237a56ee786a16568851f1 URL: https://github.com/llvm/llvm-project/commit/8e504615e9f1b27c06237a56ee786a16568851f1 DIFF: https://github.com/llvm/llvm-project/commit/8e504615e9f1b27c06237a56ee786a16568851f1.diff LOG: [LangRef] missing link, minor fix Added: Modified: llvm/docs/LangRef.rst Removed: diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index e359fc730515..1964f2416b8f 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3667,12 +3667,12 @@ a poison value. Poison value behavior is defined in terms of value *dependence*: -- Values other than :ref:`phi ` nodes and :ref:`select ` - instructions depend on their operands. +- Values other than :ref:`phi ` nodes, :ref:`select `, and + :ref:`freeze ` instructions depend on their operands. - :ref:`Phi ` nodes depend on the operand corresponding to their dynamic predecessor basic block. -- Select instructions depend on their condition operand and their - selected operand. +- :ref:`Select ` instructions depend on their condition operand and + their selected operand. - Function arguments depend on the corresponding actual argument values in the dynamic callers of their functions. - :ref:`Call ` instructions depend on the :ref:`ret ` ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 864dda5 - [InstSimplify] Add tests that fold instructions with poison operands (NFC)
Author: Juneyoung Lee Date: 2020-12-02T01:01:59+09:00 New Revision: 864dda5fd50471acaee335c1643cbd424ef319ce URL: https://github.com/llvm/llvm-project/commit/864dda5fd50471acaee335c1643cbd424ef319ce DIFF: https://github.com/llvm/llvm-project/commit/864dda5fd50471acaee335c1643cbd424ef319ce.diff LOG: [InstSimplify] Add tests that fold instructions with poison operands (NFC) Added: llvm/test/Transforms/InstSimplify/and.ll llvm/test/Transforms/InstSimplify/fcmp.ll llvm/test/Transforms/InstSimplify/fp-undef-poison.ll llvm/test/Transforms/InstSimplify/insertvalue.ll llvm/test/Transforms/InstSimplify/xor.ll Modified: llvm/test/Transforms/InstSimplify/add.ll llvm/test/Transforms/InstSimplify/call.ll llvm/test/Transforms/InstSimplify/div.ll llvm/test/Transforms/InstSimplify/extract-element.ll llvm/test/Transforms/InstSimplify/fminmax-folds.ll llvm/test/Transforms/InstSimplify/gep.ll llvm/test/Transforms/InstSimplify/icmp.ll llvm/test/Transforms/InstSimplify/insertelement.ll llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll llvm/test/Transforms/InstSimplify/mul.ll llvm/test/Transforms/InstSimplify/or.ll llvm/test/Transforms/InstSimplify/phi.ll llvm/test/Transforms/InstSimplify/rem.ll llvm/test/Transforms/InstSimplify/saturating-add-sub.ll llvm/test/Transforms/InstSimplify/select.ll llvm/test/Transforms/InstSimplify/shift.ll llvm/test/Transforms/InstSimplify/shufflevector.ll llvm/test/Transforms/InstSimplify/sub.ll Removed: llvm/test/Transforms/InstSimplify/fp-undef.ll diff --git a/llvm/test/Transforms/InstSimplify/add.ll b/llvm/test/Transforms/InstSimplify/add.ll index 21cc905688b2..b271c87d188f 100644 --- a/llvm/test/Transforms/InstSimplify/add.ll +++ b/llvm/test/Transforms/InstSimplify/add.ll @@ -30,7 +30,7 @@ define <2 x i32> @negated_operand_commute_vec(<2 x i32> %x) { define i8 @knownnegation(i8 %x, i8 %y) { ; CHECK-LABEL: @knownnegation( -; CHECK-NEXT:ret i8 0 +; CHECK-NEXT:ret i8 0 ; %xy = sub i8 %x, %y %yx = sub i8 %y, %x @@ -48,4 +48,10 @@ define <2 x i8> @knownnegation_commute_vec(<2 x i8> %x, <2 x i8> %y) { ret <2 x i8> %r } - +define i32 @poison(i32 %x) { +; CHECK-LABEL: @poison( +; CHECK-NEXT:ret i32 poison +; + %y = add i32 %x, poison + ret i32 %y +} diff --git a/llvm/test/Transforms/InstSimplify/and.ll b/llvm/test/Transforms/InstSimplify/and.ll new file mode 100644 index ..f199bd14f644 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/and.ll @@ -0,0 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instsimplify -S | FileCheck %s + +; TODO: this should be poison + +define i32 @poison(i32 %x) { +; CHECK-LABEL: @poison( +; CHECK-NEXT:ret i32 0 +; + %v = and i32 %x, poison + ret i32 %v +} diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index 6579bda52795..bfbd101b046c 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -35,6 +35,14 @@ define {i8, i1} @test_uadd3(i8 %v) { ret {i8, i1} %result } +define {i8, i1} @test_uadd3_poison(i8 %v) { +; CHECK-LABEL: @test_uadd3_poison( +; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } +; + %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v, i8 poison) + ret {i8, i1} %result +} + define {i8, i1} @test_uadd4(i8 %v) { ; CHECK-LABEL: @test_uadd4( ; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } @@ -43,6 +51,14 @@ define {i8, i1} @test_uadd4(i8 %v) { ret {i8, i1} %result } +define {i8, i1} @test_uadd4_poison(i8 %v) { +; CHECK-LABEL: @test_uadd4_poison( +; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } +; + %result = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 poison, i8 %v) + ret {i8, i1} %result +} + define i1 @test_sadd1() { ; CHECK-LABEL: @test_sadd1( ; CHECK-NEXT:ret i1 true @@ -69,6 +85,14 @@ define {i8, i1} @test_sadd3(i8 %v) { ret {i8, i1} %result } +define {i8, i1} @test_sadd3_poison(i8 %v) { +; CHECK-LABEL: @test_sadd3_poison( +; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } +; + %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v, i8 poison) + ret {i8, i1} %result +} + define {i8, i1} @test_sadd4(i8 %v) { ; CHECK-LABEL: @test_sadd4( ; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } @@ -77,6 +101,14 @@ define {i8, i1} @test_sadd4(i8 %v) { ret {i8, i1} %result } +define {i8, i1} @test_sadd4_poison(i8 %v) { +; CHECK-LABEL: @test_sadd4_poison( +; CHECK-NEXT:ret { i8, i1 } { i8 undef, i1 false } +; + %result = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 poison, i8 %v) + ret {i8, i1} %result +} + define {i8, i1} @test_usub1(i8 %V) { ; CHECK-LABEL: @test_usub1( ; CHECK-NEXT:ret { i8, i1 } zeroinitializer @@ -93,6 +125,14 @@ define {i8, i1} @test_usub2(i8 %V) {
[llvm-branch-commits] [llvm] 3b6f4c5 - [ReleaseNotes] Mention freeze instruction
Author: Juneyoung Lee Date: 2020-02-27T21:41:48+09:00 New Revision: 3b6f4c544be48dcfa663cfb62da3fd4e779954a5 URL: https://github.com/llvm/llvm-project/commit/3b6f4c544be48dcfa663cfb62da3fd4e779954a5 DIFF: https://github.com/llvm/llvm-project/commit/3b6f4c544be48dcfa663cfb62da3fd4e779954a5.diff LOG: [ReleaseNotes] Mention freeze instruction Reviewers: hans, nlopes, regehr Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75226 Added: Modified: llvm/docs/ReleaseNotes.rst Removed: diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 69a055aeef63..a788f8f60042 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -86,8 +86,8 @@ Non-comprehensive list of changes in this release * Windows Control Flow Guard: the ``-cfguard`` option now emits CFG checks on - indirect function calls. The previous behavior is still available with the - ``-cfguard-nochecks`` option. Note that this feature should always be used + indirect function calls. The previous behavior is still available with the + ``-cfguard-nochecks`` option. Note that this feature should always be used with optimizations enabled. * ``Callbacks`` have been added to ``CommandLine Options``. These can @@ -123,6 +123,10 @@ Changes to the LLVM IR that correctly converted 80-90% of Clang tests. Some manual work will almost certainly still be needed. +* A new `freeze` instruction is added. The `freeze` instruction is used to stop + IR-level propagation of undef and poison values. Currently its support is + preliminary; a freeze-equivalent operation for SelDag/MIR needs to be added. + Changes to building LLVM ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits