How does llvm ir handle different kind of short circuits? - llvm

For the following code in C:
void test(int a, int b, int c){
if(a > 1 && (b == 2 || c == 3))
b = a + c;
else
c = a + b;
return;
}
The CFG is as following:
But when I change the if on line 2 to while:
void test(int a, int b, int c){
while(a > 1 && (b == 2 || c == 3))
b = a + c;
c = a + b;
return;
}
Then the CFG is changed to:
So the basic block lor.end and land.end are generated, but they are not corresponding to any statement in the program. Why does while.cond not connects to while.end directly just like entry -> if.else in the first CFG? In other words, why are lor.end and land.end generated? It seems that the way of handling short circuits in if statements are different from that in loop statements. What causes this difference?
compiling script(calng/llvm 7.0.1): clang -emit-llvm -c -g -fno-discard-value-names file_name.c

Related

Is it possible to reduce test cases by taking expressions out from if statement?

It might be a little silly question.
But I am contemplating this issue.
For example, if I extract test cases for below code
it will have 32 test cases to achieve 100% multiple condition coverage
int foo(int a, int b, int c, int d, int e)
{
if (a && b || c && d || e)
return 100;
else
return 200;
}
An then if I change above code into below which need only 2 test cases to achieve 100% multiple condition coverage
In this case, can I say my test code achieve 100% multiple condition coverage?
int foo(int a, int b, int c, int d, int e)
{
bool cond = a && b || c && d || e;
if (cond)
return 100;
else
return 200;
}

warning C4715: not all control paths return a value c++ - cant pass a test

I'm having an issue with this code:
The problem is I'm constantly getting warning C4715 despite the fact .exe is running correctly and it gives correct answer to a problem I'm trying to resolve. The warning makes it impossible to pass the task inside the app. Please give me a clue why 'return' used by me in the if sentences doesn't work.
#include <utility>
#include <iostream>
std::pair<int, int> solve(int a, int b) {
if (a == 0 || b == 0) {
std::pair <int, int> kek(a, b);
return kek;
}
else if (a >= 2 * b) {
a = (a - (2 * b));
solve(a, b);
}
else if (b >= 2 * a) {
b = (b - (2 * a));
solve(a, b);
}
else {
std::pair <int, int> kek(a, b);
return kek;
}
}
int main() {
bool result{ solve(22, 5) == std::make_pair(0,1) };
std::cout << result;
return 0;
}
Your solve function won't execute return statement if a == 0 || b == 0 is not true and either one of a >= 2 * b or b >= 2 * a is true.
It seems that the two solve(a, b); in the solve function should be return solve(a, b);.

How do I solve this middle number problem?

Write a program where the user inputs 3 float numbers and the program checks which is medium size number. Example : a = 1.5, b = 7.8, and c = 3.0 and output should be c.
This is what I've tried and it worked for one case, but I'm still doing too much spaghetti code and I'm still learning how to write code efficiently.
My code:
#include <stdio.h>
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
if(a < b && c < a)
printf("%.1f", a);
else if(b < a && b > c)
printf("%.1f", b);
else if(c > a && c < b)
printf("%.1f", c);
else
{
printf("not good"); //I wrote this part to check if the code is good
}
return 0;
}
I'm still trying to get the hang of the if loops and I was just confused with this problem. Do you have any suggestions?
think of like, if a is medium , then b is medium, then c is medium. Check if that hepls!
#include <stdio.h>
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
if((a > b && a < c) || (a > c && a < b) )
printf("%.1f", a);
else if((b > a && b < c) || (b > c && b < a))
printf("%.1f", b);
else if((c > a && c < b) || (c > b && c < a))
printf("%.1f", c);
else
{
printf("not good"); //I wrote this part to check if the code is good
}
return 0;
}
If you can use C++:
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
float a, b, c;
scanf("%f %f %f", &a, &b, &c);
// Put them in a vector. Could use array, but vector more flexible
vector<float> vals = {a,b,c};
// Sort in numerical order
sort (vals.begin(),vals.end());
// Display the middle one
printf("%.1f", vals[1]);
return 0;
}

bit representation of unsigned int zero

I ran into a behavior which I didn't expect using bitwise operations on unsigned ints. I'll cut right to my example.
unsigned int a = 0;
unsigned int b = 0;
std::printf("a & b: %u\n", a & b);
std::printf("a == b: %i\n", a == b);
std::printf("a & b == a: %i\n", a & b == a);
The above code produces the following output:
a & b: 0
a == b: 1
a & b == a: 0
The last line is what confuses me. Shouldn't a & b == a evaluate to true, since a & b == (unsigned int)0 and a == (unsigned int)0?
You're getting this behavior because you didn't realize == comes before & in the C operator precedence table. In fact, a good compiler will warn you straight away about your code:
t.cpp:10:35: warning: & has lower precedence than ==; == will be evaluated first [-Wparentheses]
std::printf("a & b == a: %i\n", a & b == a);
^~~~~~~~
t.cpp:10:35: note: place parentheses around the '==' expression to silence this warning
std::printf("a & b == a: %i\n", a & b == a);
^
( )
t.cpp:10:35: note: place parentheses around the & expression to evaluate it first
std::printf("a & b == a: %i\n", a & b == a);
^
( )
Make sure your warnings are turned on, like g++ -Wall -Wextra -Werror.
You should write:
(a & b) == a
Now you'll get 1 since a & b will be evaluated first:
(a & b) = 0, 0 == 0 is 1.
In your case, a & b == a is evaluated as a & (b == a), b == a is 1, and a & 1 is 0.
Due to =='s precedence over &, a & b == a gets evaluated as a & (b == a) (and not as (a & b) == a as you appear to have expected).

Relatively Prime Numbers

How to make a function in c++ to determine if two entered numbers are relatively prime (no common factors)?
For example "1, 3" would be valid, but "2, 4" wouldn't.
Galvanised into action by Jim Clay's incautious comment, here is Euclid's algorithm in six lines of code:
bool RelativelyPrime (int a, int b) { // Assumes a, b > 0
for ( ; ; ) {
if (!(a %= b)) return b == 1 ;
if (!(b %= a)) return a == 1 ;
}
}
Updated to add: I have been out-obfuscated by this answer from Omnifarious, who programs the gcd function thus:
constexpr unsigned int gcd(unsigned int const a, unsigned int const b)
{
return (a < b) ? gcd(b, a) : ((a % b == 0) ? b : gcd(b, a % b));
}
So now we have a three-line version of RelativelyPrime:
bool RelativelyPrime (int a, int b) { // Assumes a, b > 0
return (a<b) ? RelativelyPrime(b,a) : !(a%b) ? (b==1) : RelativelyPrime (b, a%b);
}
One of the many algorithms for computing the Greatest Common Denominator.