mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 23:26:39 +00:00

The icmp is being folded in phi only if they belong in the same BB. This patch extends the same beyond the BB. Have seen scenarios where this seems to be beneficial. Differential Revision: https://reviews.llvm.org/D157740
112 lines
2.9 KiB
C
112 lines
2.9 KiB
C
// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
|
|
// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks %s %t-callbacks.o -o %t
|
|
// RUN: %run %t FooBarBaz 2>&1 | FileCheck %s
|
|
//
|
|
// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -DORIGINS -c %s -o %t-callbacks-orig.o
|
|
// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks -mllvm -dfsan-track-origins=1 -DORIGINS %s %t-callbacks-orig.o -o %t-orig
|
|
// RUN: %run %t-orig FooBarBaz 2>&1 | FileCheck %s
|
|
|
|
// Tests that callbacks are inserted for conditionals when
|
|
// -dfsan-conditional-callbacks is specified.
|
|
|
|
#include <assert.h>
|
|
#include <sanitizer/dfsan_interface.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef CALLBACKS
|
|
// Compile this code without DFSan to avoid recursive instrumentation.
|
|
|
|
extern dfsan_label LabelI;
|
|
extern dfsan_label LabelJ;
|
|
extern dfsan_label LabelIJ;
|
|
|
|
void my_dfsan_conditional_callback(dfsan_label Label, dfsan_origin Origin) {
|
|
assert(Label != 0);
|
|
#ifdef ORIGINS
|
|
assert(Origin != 0);
|
|
#else
|
|
assert(Origin == 0);
|
|
#endif
|
|
|
|
static int Count = 0;
|
|
switch (Count++) {
|
|
case 0:
|
|
assert(Label == LabelI);
|
|
break;
|
|
case 1:
|
|
assert(Label == LabelJ);
|
|
break;
|
|
case 2:
|
|
assert(Label == LabelIJ);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
fprintf(stderr, "Label %u used as condition\n", Label);
|
|
}
|
|
|
|
#else
|
|
// Compile this code with DFSan and -dfsan-conditional-callbacks to insert the
|
|
// callbacks.
|
|
|
|
dfsan_label LabelI;
|
|
dfsan_label LabelJ;
|
|
dfsan_label LabelIJ;
|
|
|
|
extern void my_dfsan_conditional_callback(dfsan_label Label,
|
|
dfsan_origin Origin);
|
|
|
|
int main(int Argc, char *Argv[]) {
|
|
assert(Argc == 2);
|
|
|
|
dfsan_set_conditional_callback(my_dfsan_conditional_callback);
|
|
|
|
int result = 0;
|
|
// Make these not look like constants, otherwise the branch we're expecting
|
|
// may be optimized out.
|
|
int DataI = (Argv[0][0] != 0) ? 1 : 0;
|
|
int DataJ = (Argv[1][0] != 0) ? 2 : 0;
|
|
LabelI = 1;
|
|
dfsan_set_label(LabelI, &DataI, sizeof(DataI));
|
|
LabelJ = 2;
|
|
dfsan_set_label(LabelJ, &DataJ, sizeof(DataJ));
|
|
LabelIJ = dfsan_union(LabelI, LabelJ);
|
|
|
|
assert(dfsan_get_label(DataI) == LabelI);
|
|
|
|
// CHECK: Label 1 used as condition
|
|
if (DataI) {
|
|
result = 42;
|
|
}
|
|
|
|
fprintf(stderr, "Result is %d\n", result);
|
|
assert(dfsan_get_label(DataJ) == LabelJ);
|
|
|
|
// CHECK: Label 2 used as condition
|
|
switch (DataJ) {
|
|
case 1:
|
|
result += 10000;
|
|
break;
|
|
case 2:
|
|
result += 4200;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
int tainted_cond = ((DataI * DataJ) != 1);
|
|
fprintf(stderr, "Result is %d\n", result);
|
|
assert(dfsan_get_label(tainted_cond) == LabelIJ);
|
|
|
|
// CHECK: Label 3 used as condition
|
|
result = tainted_cond ? result + 420000 : 9;
|
|
|
|
fprintf(stderr, "Result is %d\n", result);
|
|
assert(result == 424242);
|
|
return 0;
|
|
}
|
|
|
|
#endif // #ifdef CALLBACKS
|