Index: llvm/test/Transforms/Attributor/potential.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Attributor/potential.ll @@ -0,0 +1,128 @@ +; Test for multiple potential values +; +; potential-test 1 +; int iszero(int c) { return c == 0; } +; int potential_test1(int c) { return iszero(c ? 1 : -1); } + +define dso_local i32 @potential_test1(i32 %0) { + %2 = icmp eq i32 %0, 0 + %3 = select i1 %2, i32 -1, i32 1 + %4 = tail call i32 @iszero(i32 %3) + ret i32 %4 +} + +define internal i32 @iszero(i32 %0) { + %2 = icmp eq i32 %0, 0 + %3 = zext i1 %2 to i32 + ret i32 %3 +} + +; potential-test 2 +; +; potential values of argument of iszero are {1,-1} +; potential value of returned value of iszero is 0 +; +; int call_with_two_values(int x) { return iszero(x) + iszero(-x); } +; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); } + +define dso_local i32 @potential_test2(i32 %0) { + %2 = tail call i32 @call_with_two_values(i32 1) + %3 = tail call i32 @call_with_two_values(i32 -1) + %4 = add nsw i32 %3, %2 + ret i32 %4 +} + +define internal i32 @call_with_two_values(i32 %0) { + %2 = tail call i32 @iszero(i32 %0) + %3 = sub nsw i32 0, %0 + %4 = tail call i32 @iszero(i32 %3) + %5 = add nsw i32 %4, %2 + ret i32 %5 +} + + +; potential-test 3 +; +; potential values of returned value of f are {0,1} +; potential values of argument of g are {0,1} +; potential value of returned value of g is 1 +; then returned value of g can be simplified +; +; int zero_or_one(int c) { return c < 2; } +; int potential_test3() { return zero_or_one(iszero(0))+zero_or_one(iszero(1)); } + + +define dso_local i32 @potential_test3(i32 %0) { + %2 = tail call i32 @iszero(i32 0) + %3 = tail call i32 @zero_or_one(i32 %2) + %4 = tail call i32 @iszero(i32 1) + %5 = tail call i32 @zero_or_one(i32 %4) + %6 = add nsw i32 %5, %3 + ret i32 %6 +} + +define internal i32 @zero_or_one(i32 %0) { + %2 = icmp slt i32 %0, 2 + %3 = zext i1 %2 to i32 + ret i32 %3 +} + + +; potential-test 4,5 +; +; simplified +; int potential_test4(int c) { return return1or3(c) == 2; } +; int potential_test5(int c) { return return1or3(c) == return2or4(c); } +; +; not simplified +; int potential_test6(int c) { return return1or3(c) == 3; } +; int potential_test7(int c) { return return1or3(c) == return3or4(c); } + +define dso_local i32 @potential_test4(i32 %0) { + %2 = tail call i32 @return1or3(i32 %0) + %3 = icmp eq i32 %2, 2 + %4 = zext i1 %3 to i32 + ret i32 %4 +} + +define dso_local i32 @potential_test5(i32 %0) { + %2 = tail call i32 @return1or3(i32 %0) + %3 = tail call i32 @return2or4(i32 %0) + %4 = icmp eq i32 %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +} + +define dso_local i32 @potential_test6(i32 %0) { + %2 = tail call i32 @return1or3(i32 %0) + %3 = icmp eq i32 %2, 3 + %4 = zext i1 %3 to i32 + ret i32 %4 +} + +define dso_local i32 @potential_test7(i32 %0) { + %2 = tail call i32 @return1or3(i32 %0) + %3 = tail call i32 @return3or4(i32 %0) + %4 = icmp eq i32 %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +} + +define internal i32 @return1or3(i32 %0) { + %2 = icmp eq i32 %0, 0 + %3 = select i1 %2, i32 1, i32 3 + ret i32 %3 +} + +define internal i32 @return2or4(i32 %0) { + %2 = icmp eq i32 %0, 0 + %3 = select i1 %2, i32 2, i32 4 + ret i32 %3 +} + +define internal i32 @return3or4(i32 %0) { + %2 = icmp eq i32 %0, 0 + %3 = select i1 %2, i32 3, i32 4 + ret i32 %3 +} +